tags:

views:

726

answers:

4

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.

+1  A: 

EnumSet implements Serializable, so you could just write it out with an ObjectOutputStream.

Michael Myers
+2  A: 

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 :(

Jon Skeet
Reflection dark magic could be used to retrieve the value, though this would be neither "quick" nor "simple".
Greg Case
EnumSet is actually abstract, so it would be even worse.
Michael Myers
+2  A: 

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.

Dave Ray
You really should check that the ordinals are less than 64. long (+Class) to EnumSet should be doable - you can get all of the values from an enum.
Tom Hawtin - tackline
A: 

The (typical - it's not mandated) implementation of EnumSet uses the enum values' ordinals. You should not assume that ordinals will always stay the same. So, if you want to store enum sets efficiently using ordinals, you should also store a map from enum name to ordinal (probably stored as a sequence of enum names).

EnumSet itself doesn't appear to have a great serialised form. It just dumps out an of enums. The body of which will be transcribed into a series of integer object references rather than a bit set.

Tom Hawtin - tackline