6

Is there a better way of creating arrays from elements of an enum:

    public static enum LOGICAL {
        AND ("&", "AND"),
        OR ("||", "OR");

        public final String symbol;
        public final String label;

        LOGICAL(String symbol, String label) {
            this.symbol=symbol;
            this.label=label;
        }
    }

    public static final String[] LOGICAL_NAMES = new String[LOGICAL.values().length];
    static{
        for(int i=0; i<LOGICAL.values().length; i++)
            LOGICAL_NAMES[i]=LOGICAL.values()[i].symbol;
    }

    public static final String[] LOGICAL_LABELS = new String[LOGICAL.values().length];
    static{
        for(int i=0; i<LOGICAL.values().length; i++)
            LOGICAL_LABELS[i]=LOGICAL.values()[i].label;
    }

3 Answers 3

3

Personally I wouldn't expose them as an array, whose contents can be changed by anyone. I'd probably use an unmodifiable list instead - and probably expose that via a property rather than as a field. The initialization would be something like this:

private static final List<String> labels;
private static final List<String> values;

static
{
    List<String> mutableLabels = new ArrayList<String>();
    List<String> mutableValues = new ArrayList<String>();
    for (LOGICAL x : LOGICAL.values())
    {
         mutableLabels.add(x.label);
         mutableValues.add(x.value);
    }
    labels = Collections.unmodifiableList(mutableLabels);
    values = Collections.unmodifiableList(mutableValues);
}

(If you're already using Guava you might even want to use ImmutableList instead, and expose the collections that way to make it clear that they are immutable.)

Sign up to request clarification or add additional context in comments.

1 Comment

Yes! I wish there is a ImmutableList in standard Java API.
2

No. That seems the proper way. Even if there was some utility, it would rely on reflection

If you are using it often cache it in the enum

4 Comments

Please explain what do you mean by "caching". Move the static arrays to the enum body?
Store it in a field so that you don't compute it everytime
I was convinced that this code would only run ONCE (on the first access to the class).
ah, yes - I missed the constant definition. So you are already caching it.
2

If you use your values very frequently and your enumeration gets bigger use Maps. Declare the following in your class.

private static EnumMap<LOGICAL,String> symbols = new EnumMap<LOGICAL, String>(LOGICAL.class);

and then just below it:

static{
    for(LOGICAL i : LOGICAL.values().)
        symbols.put(i, i.symbol);
}

then you can use symbols.values() or symbols.get(LOGICAL.AND) etc.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.