Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting the value from an EnumSet in Java

Tags:

java

If you use an EnumSet to store conventional binary values (1,2,4 etc), then when there are less than 64 items, I am led to believe that this is stored as a bit vector and is represented efficiently as a long. Is there a simple way to get the value of this long. I want a quick and simple way to store the contents of the set in either a file or database.

If I was doing this the old way, I'd just use a long, and do the bit twidling myself, despite all the issues of typesafety etc.

like image 994
Miles D Avatar asked Dec 12 '08 17:12

Miles D


3 Answers

As far as I'm aware, this isn't exposed. You could basically rewrite it yourself - have a look at the code for EnumSet to get an idea of the code - but it's a pity there isn't a nicer way of getting at it :(

like image 62
Jon Skeet Avatar answered Sep 19 '22 00:09

Jon Skeet


I don't think this can be done in a generic way. Converting to a long is pretty easy:

public static <T extends Enum<T>> long enumSetToLong(EnumSet<T> set)
{
    long r = 0;
    for(T value : set)
    {
        r |= 1L << value.ordinal();
    }
    return r;
}

I don't know how you can possibly convert from a long back to EnumSet generically. There's no way (short of reflection) I know of to get at the values array of the enumeration to do the lookup. You'd have to do it on a per-enum basis.

I think serialization is the way to go. Just serializing as a long would be more susceptible to versioning errors, or bugs caused by rearranging the constants in the enum.

like image 23
Dave Ray Avatar answered Sep 19 '22 00:09

Dave Ray


As mentioned by Jon Skeet this information is not exposed. But Dave Ray showed how to calculate it easily. I made a library that makes such conversions a lot simpler. It also checks that there really arent more than 64 elements if you use "long". I had to create a new data type but it can be used just like a BitSet or an EnumSet. Note that this requires Java 8 or newer as this uses interfaces with default implementations.

Here's the link: http://claude-martin.ch/enumbitset/

Example:

  static enum MyEnum implements EnumBitSetHelper<MyEnum> { A, B, C }
  public static void main(final String[] args) {
    final EnumBitSet<MyEnum> set = EnumBitSet.of(MyEnum.A, MyEnum.C);
    long bitmask = set.toLong(); // = 3
  }
like image 37
Claude Martin Avatar answered Sep 18 '22 00:09

Claude Martin