Question

I have an interface

public interface TerminalSymbol {
    // methods ...
}

an enum

// common usage enum that I need
public enum Common implements TerminalSymbol {
    EPSILON;

    @Override
    // methods ...
}

and I'd like to do something like:

enum Term implements TerminalSymbol {
    A, B, C, ...

    @Override
    // methods ...
}

EnumSet<? extends TerminalSymbol> terminalSymbols = EnumSet.allOf(Term.class);
terminalSymbol.add(Common.EPSILON); // this line gives me error

and that error is (in my case):

The method add(capture#1-of ? extends TerminalSymbol) in the type AbstractCollection<capture#1-of ? extends TerminalSymbol> is not applicable for the arguments (Common)

now I know that if I use Set<SomeInterface> I could prevent this type of error (and I could continue with my developing of my class representing a formal grammar) but I'd like to use EnumSet because it's likely to be more efficient than HashSet. How can I solve this problem?

Was it helpful?

Solution 2

EnumSet draws its efficiency from the key constraint that it contains strictly members of a single enum. It achieves this by efficiently storing its state with reliance on ordinal number of each enum member, basically behaving like a BitSet. So unfortunately you won't be able to reap its benefits if you want multiple enums.

The closest you can get to this goal is by devising your own numbering scheme which is distinct across all your enums, and using a BitSet to efficiently store them.

OTHER TIPS

The EnumSet can only contain members of one enum class.

From the Java API documentation:

All of the elements in an enum set must come from a single enum type that is specified, explicitly or implicitly, when the set is created.

As you note, an alternative is to use Set<TerminalSymbol>.

EnumSet is a special implementation of Set interface for enums only. One instance of EnumSet can work with specific enum only because its implementation is based on ordinal of enum.

You created EnumSet for Term and try to add there enum member of Common. This is obviously impossible. You should either create EnumSet for Common or if you want to store elements of both enums there use other implementation of Set, e.g. HashSet.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top