enum Modifier {
DEFAULT, PRIVATE, PROTECTED, PUBLIC, STATIC, FINAL
}
DEFAULT ordinal: 0 bitmask: 2^0 = (int) 1
PRIVATE ordinal: 1 bitmask: 2^1 = (int) 2
PROTECTED ordinal: 2 bitmask: 2^2 = (int) 4
PUBLIC ordinal: 3 bitmask: 2^3 = (int) 8
STATIC ordinal: 4 bitmask: 2^3 = (int) 16
FINAL ordinal: 5 bitmask: 2^4 = (int) 32
Bit mask for a given position is done with a shift left.
1 << 0 = 1
1 << 1 = 2
1 << 2 = 4
1 << 3 = 8
1 << 4 = 16
1 << 5 = 32
I.e, bit mask for a given enum value is 1 << enum.ordinate()
.
Test if a bit is not set with (bitset & mask) == 0
, then set the bit with bitset |= bitmask
.
int bitset = 0;
for (Modifier modifier : modifiers) {
int mask = 1 << modifier.ordinal();
if ((bitset & mask) == 0) {
bitset |= mask;
} else {
return false;
}
}
return true;
Accumulate all the bits for the expected values: bitset |= (1 << modifier.ordinal())
Loop over the actual values and test if a bit is set with: (bitset & (1 << modifier.ordinal())) == 0
int bitset = 0;
for (Modifier modifier : expected) bitset |= (1 << modifier.ordinal());
for (Modifier modifier : actual) {
if ((bitset & (1 << modifier.ordinal())) == 0) {
return false;
}
}
return true;
Compute a mask for the subset that is tested.
E.g.
DEFAULT, PRIVATE, PROTECTED, PUBLIC = 2^0 + 2^1 + 2^2 + 2^3 = 1 + 2 + 4 + 8 = 15
Accumulate a bitset for each enum values: bitset |= (1 << modifier.ordinal())
.
Restrict the bitset to the subset: bitset & 15
Test if zero or one bit is set: (access & (access - 1)) == 0
int bitset = 0;
for (Modifier modifier : modifiers) {
bitset |= (1 << modifier.ordinal());
int access = bitset & 15;
if ((access & (access - 1)) == 0) {
// zero or one bit set
continue;
}
return false;
}
return true;
This can be used for implementing a state machine.
The state or states are maintained in an AtomicInteger
, each state and transition is a a bitmask.
AtomicInteger bitset; //...
bitset.getAndUpdate(v -> v < 0 ? v | mask : v);