javagenericscollectionsenumset

How to create an EnumSet of a collection of unspecified objects


Given data:

I am presented with a collection:

Collection<?> collection

This collection may contain anything. It could be "normal" classes, or it could be enum values.

The class is known at this point in my code. I am given:

Class<?> clazz

Which is guaranteed to be the class of objects contained in the collection. There is no class-mixing.


Goal:

Should the clazz of the objects in the collection be any kind of enum, I wish to create an EnumSet of the objects contained. For my purposes, I could just take the given collection an run with it. However enum sets are just way more efficient, AFAIK.


What I have achieved:

  1. Determined if I am dealing with an Enum type of class by using:
if (Enum.class.isAssignableFrom(clazz)) {
    //noinspection unchecked
    Class<? extends Enum<?>> enumClass = ((Class<? extends Enum<?>>) clazz);
    System.out.println("enumClass: " + enumClass.getSimpleName()); // prints the correct class!
    // what now? :-(
}

What I am struggling with:

Anything beyond that, it feels like I have already tried every way of casting things at the wall and seeing what sticks. And when it comes to trying to create a generic EnumSet, I have never even gotten to the point where my IDE would let me compile.


Answer found

From the answer of @JayC667 below (thank you very much for your effort), I have abstracted the following answer for my purposes:

if (Enum.class.isAssignableFrom(clazz)) {
    EnumSet<?> enumSet = collection.isEmpty() ? EnumSet.noneOf(((Class<? extends Enum>) clazz)) : EnumSet.copyOf((Collection<Enum>) collection);
}

Solution

  • I am not sure if this answers your question...

    Central piece is EnumSet.copyOf((Collection<TestEnum1>) collection). Code works OK for the test, but I'm not sure where you're going with it, so... good luck ;-)

    package stackoverflow;
    
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.EnumSet;
    import java.util.HashSet;
    import java.util.Set;
    
    public class EnumSetMess {
    
        public enum TestEnum1 {
            A, B, C;
        }
        public enum TestEnum2 {
            A, B, C;
        }
    
    
        public static void main(final String[] args) {
            {
                final ArrayList<TestEnum1> list = new ArrayList<>();
                list.add(TestEnum1.A);
                list.add(TestEnum1.B);
                list.add(TestEnum1.C);
                final Set<?> res = x(list, TestEnum1.class);
                System.out.println("Set: " + res.getClass().getSimpleName());
                for (final Object r : res) {
                    System.out.println("\t" + r);
                }
            }
            {
                final ArrayList<TestEnum2> list = new ArrayList<>();
                list.add(TestEnum2.A);
                list.add(TestEnum2.B);
                list.add(TestEnum2.C);
                final Set<?> res = x(list, TestEnum2.class);
                System.out.println("Set: " + res.getClass().getSimpleName());
                for (final Object r : res) {
                    System.out.println("\t" + r);
                }
            }
            {
                final ArrayList<String> list = new ArrayList<>();
                list.add("sA");
                list.add("sB");
                list.add("sC");
                final Set<?> res = x(list, String.class);
                System.out.println("Set: " + res.getClass().getSimpleName());
                for (final Object r : res) {
                    System.out.println("\t" + r);
                }
            }
        }
    
    
        static Set<?> x(final Collection<?> collection, final Class<?> clazz) {
            if (Enum.class.isAssignableFrom(clazz)) {
                //noinspection unchecked
                // final Class<? extends Enum<?>> enumClass = ((Class<? extends Enum<?>>) clazz); // actually we dont need this line
                //System.out.println("enumClass: " + enumClass.getSimpleName()); // prints the correct class!  // actually we dont need this line
                // what now? :-(
                // final EnumSet<?> ret = EnumSet.copyOf((Collection<TestEnum1>) collection); // you COULD write this line here thanx to type erasure.
                final EnumSet<?> ret = EnumSet.copyOf((Collection<? extends Enum>) collection); // tho this looks cleaner
    
                return ret;
            }
            return new HashSet<>(collection);
        }
    
    }
    

    The output is

    enumClass: TestEnum1
    Set: RegularEnumSet
        A
        B
        C
    enumClass: TestEnum2
    Set: RegularEnumSet
        A
        B
        C
    Set: HashSet
        sC
        sA
        sB