I am using a library that concatenates one or more enums by ORing their values like this:
TestEnum {
VAL1(0x00000001),
VAL2(0x00000002),
VAL3(0x00000100),
VAL4(0x00000200),
VAL5(0x00000400),
VAL6(0x00000800),
VAL7(0x00001000),
VAL8(0x00002000),
VAL9(0x00004000),
VAL10(0x00008000),
// special values
VAL11(0x00000000),
VAL12(0x00000010),
VAL13(0x00000020),
VAL14(0x00000030);
private static final Map<Integer, TestEnum> TEST_ENUM_MAP;
// constructor, populate map etc.
public static TestEnum fromValue(final int value) {
return TEST_ENUM_MAP.get(value);
}
}
int valuesAsInt = 0;
for (TestEnum testEnum : TestEnum.values()) {
valuesAsInt |= testEnum.getValue();
}
I need to extract the enums that were combined to produce valueAsInt
keeping in mind that:
This is what I did:
private static final int MASK_FOR_SPECIAL_ENUMS = 0x000000FF;
private static final ImmutableSet<TestEnum> SPECIAL_ENUMS = ImmutableSet.copyOf(Sets.newHashSet(TestEnum.VAL11, TestEnum.VAL12, TestEnum.VAL13, TestEnum.VAL14));
private void lookupTestEnums(final int valueAsInt) {
TestEnum testEnum = TestEnum.fromValue(valueAsInt & MASK_FOR_SPECIAL_ENUMS);
if (testEnum == null || !SPECIAL_ENUMS.contains(testEnum)) {
throw new ExceptionType("");
}
}
Just ANDing with the mask isn't sufficient because it'll return positive results for TestEnum values, VAL1 (0x00000001)
etc.
Is there a better way of doing this?
It appears that your MASK_FOR_SPECIAL_ENUMS
must be equal to 0x000000F0
, not 0x000000FF
.
Then, after checking for validity, your lookup method needs to loop through values VAL1 through VAL10, and collect those that match.
In other words, something like this:
private static final int SPECIAL_MASK = 0x000000F0;
int specialValue = valueAsInt & SPECIAL_MASK;
int nonSpecialBits = valueAsInt & ~SPECIAL_MASK;
for (TestEnum testEnum : TestEnum.values())
{
int value = testEnum.getValue();
if( (value & SPECIAL_MASK) != 0 )
continue; //this is one of the special values; ignore.
if( (value & nonSpecialBits) == value )
collection.add( testEnum );
}
Your question does not state that there can be only one special value; it states there must be one, which is another way of saying at least one, so it is not possible to do what you want, because:
0x00000010 | 0x00000020 == 0x00000030
Once 0x00000010
and 0x00000020
have been accumulated in the collective OR
value, the value will be indistinguishable from an accumulated value that has 0x00000030
in it.
However, if the special value was 0x00000040
, a simple bit-mask would work.
User contributions licensed under CC BY-SA 3.0