67

Is it possible to create ArrayList of enum values (and manipulate it)? For example:

enum MyEnum
{
   ONE, TWO
}

MyEnum my = MyEnum.ONE;
List <?> al = new ArrayList <?>();
al.add(my);
al.remove(al.size()-1);

7 Answers 7

153

You can simply write

new ArrayList<MyEnum>(Arrays.asList(MyEnum.values()));
Sign up to request clarification or add additional context in comments.

Comments

47

tl;dr

Can you make and edit a collection of objects from an enum? Yes.

If you do not care about the order, use EnumSet, an implementation of Set.

enum Animal{ DOG , CAT , BIRD , BAT ; }

Set<Animal> flyingAnimals = EnumSet.of( BIRD , BAT );

Set<Animal> featheredFlyingAnimals = flyingAnimals.clone().remove( BAT ) ;

If you care about order, use a List implementation such as ArrayList. For example, we can create a list of a person’s preference in choosing a pet, in the order of their most preferred.

List< Animal > favoritePets = new ArrayList<>() ;
favoritePets.add( CAT ) ;  // This person prefers cats over dogs…
favoritePets.add( DOG ) ;  // …but would accept either.
                           // This person would not accept a bird nor a bat.

For a non-modifiable ordered list, use List.of.

List< Animal > favoritePets = List.of( CAT , DOG ) ;  // This person prefers cats over dogs, but would accept either. This person would not accept a bird nor a bat. 

Details

The Answer (EnumSet) by Amit Deshpande and the Answer (.values) by Marko Topolnik are both correct. Here is a bit more info.

Enum.values

The .values() method is an implicitly declared method on Enum, added by the compiler. It produces a crude array rather than a Collection. Certainly usable.

Special note about documentation: Being unusual as an implicitly declared method, the .values() method is not listed among the methods on the Enum class. The method is defined in the Java Language Specification, and is mentioned in the doc for Enum.valueOf.

EnumSet – Fast & Small

The upsides to EnumSet include:

  • Extreme speed.
  • Compact use of memory.

To quote the class doc:

Enum sets are represented internally as bit vectors. This representation is extremely compact and efficient. The space and time performance of this class should be good enough to allow its use as a high-quality, typesafe alternative to traditional int-based "bit flags." Even bulk operations (such as containsAll and retainAll) should run very quickly if their argument is also an enum set.

Given this enum:

enum Animal
{
    DOG , CAT , BIRD , BAT ;
}

Make an EnumSet in one line.

Set<Animal> allAnimals = EnumSet.allOf( Animal.class );

Dump to console.

System.out.println( "allAnimals : " + allAnimals );

allAnimals : [DOG, CAT, BIRD, BAT]

Make a set from a subset of the enum objects.

Set<Animal> flyingAnimals = EnumSet.of( BIRD , BAT );

Look at the class doc to see many ways to manipulate the collection including adding or removing elements.

Set<Animal> featheredFlyingAnimals = 
    EnumSet.copyOf( flyingAnimals ).remove( BAT );

Natural Order

The doc promises the Iterator for EnumSet is in natural order, the order in which the values of the enum were originally declared.

To quote the class doc:

The iterator returned by the iterator method traverses the elements in their natural order (the order in which the enum constants are declared).

Frankly, given this promise, I'm confused why this is not a SortedSet. But, oh well, good enough. We can create a List from the Set if desired. Pass any Collection to constructor of ArrayList and that collection’s Iterator is automatically called on your behalf.

List<Animal> list = new ArrayList<>( allAnimals );

Dump to console.

System.out.println("list : " + list );

When run.

list : [DOG, CAT, BIRD, BAT]

In Java 10 and later, you can conveniently create a non-modifiable List by passing the EnumSet. The order of the new list will be in the iterator order of the EnumSet. The iterator order of an EnumSet is the order in which the element objects of the enum were defined on that enum.

List< Animal > nonModList = List.copyOf( allAnimals ) ;  // Or pass Animals.values() 

3 Comments

Great insight in this answer!
Hey! I created arraylist based on enum. Now, I want to get user input and store it in that array. But its not allowing to add.
@Snoke You should post a carefully written Question that shows your code, stripped down to the minimum amount of code needed to show your issue. Contrive a simple example as I did here with my four animals.
23

Yes it is definitely possible, but you will have to do

List<MyEnum> al = new ArrayList<MyEnum>();

You can then add elements to al: al.add(ONE) or al.add(TWO).

2 Comments

This returns an empty list for me.
@BasilBourque It depends on the interpretation of the question. I made a clarifying edit.
13

It is possible but you should use EnumSet instead

enum MyEnum {
    ONE, TWO;
    public static final EnumSet<MyEnum> all = EnumSet.of(ONE, TWO);
}

6 Comments

Why should an EnumSet be used? What if the OP wants an ordered list?
Yeah, will try EnumSet, but just curious about ArrayList.
@A.R.S. Elements in EnumSet are in natural order. Check the java doc
@AmitD Yes but there is no way to order them differently than their natural order, as there is with ArrayList.
EnumSet is also a Set and therefore cannot contain duplicate items.
|
1

An enum is just another class in Java, it should be possible.

More accurately, an enum is an instance of Object: http://docs.oracle.com/javase/6/docs/api/java/lang/Enum.html

So yes, it should work.

Comments

1

Here it is:

enum MyEnum
{
    ONE, TWO;
    
    public List<MyEnum> getEnumValues(){
        return new ArrayList<MyEnum>(Arrays.asList(values()));
    }
}

And you can access this as:

List<MyEnum> theValues = MyEnum.getEnumValues();

//Iterate through it.. 
for(MyEnum e : theValues){
    System.out.println(e.name); 
}

Output:

ONE
TWO

Comments

0

This is a more generic solution, that can be use for any Enum object, so be free of used.

static public List<Object> constFromEnumToList(Class enumType) {
    List<Object> nueva = new ArrayList<Object>();
    if (enumType.isEnum()) {
        try {
            Class<?> cls = Class.forName(enumType.getCanonicalName());
            Object[] consts = cls.getEnumConstants();
            nueva.addAll(Arrays.asList(consts));
        } catch (ClassNotFoundException e) {
            System.out.println("No se localizo la clase");
        }
    }
    return nueva;
}

Now you must call this way:

constFromEnumToList(MiEnum.class);

3 Comments

This is incredibly over-complicated and doesn't provide any type protection (part of the reason the enum type was added to Java).
I think enum.values() is a much easier approach to get a Collection of your enums.
booo reflection

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.