Getting all names in an enum as a String[]
Solution 1
Here's one-liner for any enum
class:
public static String[] getNames(Class<? extends Enum<?>> e) {
return Arrays.stream(e.getEnumConstants()).map(Enum::name).toArray(String[]::new);
}
Pre Java 8 is still a one-liner, albeit less elegant:
public static String[] getNames(Class<? extends Enum<?>> e) {
return Arrays.toString(e.getEnumConstants()).replaceAll("^.|.$", "").split(", ");
}
That you would call like this:
String[] names = getNames(State.class); // any other enum class will work
If you just want something simple for a hard-coded enum class:
public static String[] names() {
return Arrays.toString(State.values()).replaceAll("^.|.$", "").split(", ");
}
Solution 2
Create a String[]
array for the names and call the static values()
method which returns all the enum values, then iterate over the values and populate the names array.
public static String[] names() {
State[] states = values();
String[] names = new String[states.length];
for (int i = 0; i < states.length; i++) {
names[i] = states[i].name();
}
return names;
}
Solution 3
Here`s an elegant solution using Apache Commons Lang 3:
EnumUtils.getEnumList(State.class)
Although it returns a List, you can convert the list easily with list.toArray()
Solution 4
If you can use Java 8, this works nicely (alternative to Yura's suggestion, more efficient):
public static String[] names() {
return Stream.of(State.values()).map(State::name).toArray(String[]::new);
}
Solution 5
With java 8:
Arrays.stream(MyEnum.values()).map(Enum::name)
.collect(Collectors.toList()).toArray();
Related videos on Youtube
Konstantin
Updated on April 24, 2021Comments
-
Konstantin about 3 years
What's the easiest and/or shortest way possible to get the names of enum elements as an array of
String
s?What I mean by this is that if, for example, I had the following enum:
public enum State { NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED; public static String[] names() { // ... } }
the
names()
method would return the array{ "NEW", "RUNNABLE", "BLOCKED", "WAITING", "TIMED_WAITING", "TERMINATED" }
.-
marcolopes about 10 yearsWhy there is not a native Enum method that does exactly that it's beyond me... and also a get(index) to simplify the get of value()
-
-
JB Nizet over 11 yearsWhy call
values()
13 times, generating a new array each time, instead of caching the array in a local variable? Why use toString(), which is overridable, instead ofname()
? -
PermGenError over 11 years@JBNizet heheh, i actually tried this in my IDE and way to lazy to create an State array i guess, hehe, anyways iedited it now :)
-
JB Nizet over 11 yearsYou're still not returning the names, but the toString() values.
-
PermGenError over 11 years@JBNizet hmm, tbh, i dint really know there was a
name()
method untill now. how stupid of me :P thanks for letting me know :) -
FThompson over 11 yearsAlthough it doesn't particularly matter, a regular for loop offers better performance than a foreach loop in this situation. Plus,
values()
is called twice when it need only be called once. -
Konstantin over 11 years@Vulcan I think performance would only be an issue with this if it were run hundreds of thousands of times. Besides,
values()
is a method generated by the compiler, so I'm guessing it's pretty optimized. Finally, I remember reading somewhere that for-each loops are more efficient than standard, incremental for loops, but then again — it just doesn't matter. -
Konstantin over 11 yearsI'd do something like this as well if I needed to repeatedly get the enum names, but since the
names()
method is only called sparingly, I think generating an array on the spot is fine. -
Bohemian over 11 yearsNot the shortest :) See my answer for a one-liner (that still only invokes
vales()
once) -
ceklock over 11 yearsNot the fastest ways to do the job, but nice regex.
-
Konstantin over 11 yearsI accepted this answer, but I submitted an edit that improves the code so it's easier to read.
-
sage88 over 9 years@Konstantin considering that the foreach loop in java is implemented with a standard for loop, where ever you read that foreach loops are ever more efficient is incorrect.
-
Konstantin over 9 years@sage88 I was referring to for loops in which you retrieve elements using a numeric index, which you increment in each cycle. For example:
for (int i = 0; i < a.length; i++) /* do stuff */;
In this case, for-each loops are, in fact, more efficient. A quick SO search on the matter gives us this: stackoverflow.com/questions/2113216/… -
sage88 over 9 years@Konstantin Any time you have a data structure that allows random access, as is the case with enum values, which returns an array, a C-style for loop is faster than using a for each loop. The for each loop has to generate an iterator, which makes it slower. The link you posted gives an example of using a standard for loop on a linked list using get(i), which is of course worse. When using a non-random access data structure the for each loop is faster, but on arrays it has a greater overhead. Also, since it's a primitive array, not an ArrayList, there's no performance hit from .size().
-
sage88 over 9 yearsThough I should say that I was wrong above, for each does't use a standard for loop, it uses an iterator.
-
Daniel Bimschas about 9 yearsWhile it probably works, this implementation is quite inefficient, first creating an ArrayList, adding all elements, then creating an array and copying everything again.
-
marcolopes about 9 yearsAny time soon "everyone" will be using streams to accomplish the most basic operations... and that is not a very good idea.
-
Aquarius Power about 8 yearsand java7 compliant!
-
Eido95 over 7 yearsIn Java 8 solution, outside a method scope, instead of
e.getEnumConstants()
you may useYourEnumName.values()
-
Bohemian over 7 years@Eido95 using
YourEnumName.values()
is calling a static method on the class, which cannot be reused for any enum. UsinggetEnumConstants()
works for any enum class. The idea with this method is to recreate a utility method that you can call like the last line of the answer. -
Dan Halbert over 7 years
EnumUtils.getEnumList(enumClass)
returns the enum values, not the Strings. You could useEnumUtils.getEnumMap(enumClass).keySet()
, but the order might be different. -
stefan.m over 7 yearsconsidering the fact that the number of elements in enums is usually rather small, I think that Yura's solution will be fine for many use cases. Naturally, it will depend on the specific situation...
-
cosimo193 over 7 yearsAny reason not to use ordinal() for the index and a for each loop, like: for (State state: State.values() { names[state.ordinal()] = state.toString(); }
-
Stephan about 7 yearsWhat is
EnumUtils
? -
Bohemian over 6 yearsIn this case
toString()
works, but in the general case it does not, becausetoString()
can be be overridden. Use.name()
to reliably get the instance name as a String. -
nedlud almost 6 yearsShouldn't it be
State[] states = State.values();
-
Rauni Lillemets over 5 yearsYou should give the statistics about performance, then people can judge for themselves if the performance loss is significant or not. I suppose that most people will not have 100+ or 1000+ values for an Enum.
-
Karen Goh over 5 years@PermGenError, I would like to know how to return the values (English, L1) , L1 being the value; after comparing the arrays of string with the Enums arrays. For example, the String Arrays contains English, etc etc, but I want to return a list of L1, L2 etc if it matches the ones in the Enums.
-
Line over 5 years
-
Line over 5 years@wutzebaer downvoting because this soultion isn't complete - it doesn't return array
-
ralphgabb over 5 yearsif you want a custom label for your enum, override toString() in your enum class.
-
Carmageddon over 4 yearsCan you please explaing
Class<? extends Enum<?>> e
? -
Bohemian over 4 years@Carmageddon
Class<? extends Enum<?>> e
basically means "anyenum
class", and in more detail meanse
is aClass
whose type is (or is a subtype of)Enum<?>
. Allenum
classes implicitly extend theEnum
class, whose type is a self-referencing type, ieEnum<E extends Enum<E>>
-
EngNjuguna about 3 yearsCreate a new String array. You can then populate it with values() from your enum by using the enhanced for-loop to loop through the enum.
-
Boško Bezik about 3 yearsNo need to use Streams. A simple
for
loop and a temporary array would do the trick. -
Bohemian about 3 years@BoškoBezik there’s no need to ever use streams for anything, but they make the code neater and hopefully easier to read, which is code’s purpose.