Question

So I'm converting some bitfields in our application to use EnumSet instead, and I'm curious if there's a better way to do a comparison for X|Y. Currently we do something like:

if(bitfield & (X | Y) != 0) {
    //do stuff
}

The EnumSet equivalent seems to be:

if(enumSet.contains(X) || enumSet.contains(Y)) {
    //do stuff
}

Is there a cleaner way to do this? I know you can check for containsAll() like so:

EnumSet flagsToCheck = EnumSet.of(X, Y);
if(enumSet.containsAll(flagsToCheck)) {
    //do stuff
}

But that's for a scenario where you want to know if (X & Y) is set. Is there an equivalent way to check for (X | Y)? I would think there would be something like a containsAny() method, but I don't see anything that seems to have that effect.

Was it helpful?

Solution

I would say the existing approach is more readable than your bitwise approach. It says exactly what you mean: if the set contains X, or the set contains Y... Keep it as it is. It's already clean.

If the set becomes larger, you could use:

EnumSet<Foo> valid = EnumSet.of(Foo.X, Foo.Y, Foo.A, Foo.B);
valid.retainAll(enumSet);
if (valid.isEmpty()) {
    ...
}

But I'd only keep that for larger cases. For two or three options I'd use the longhand form.

OTHER TIPS

You can use the AbstractSet method removeAll (true if any of the elements was found). Obviously, probably you want to do that with a clone of the original set.

If you can't update the set, just create a new one... @assylias is right. An option to that is to just create a new set based on the enum values you want and change/verify accordingly.

public enum ResultingState {
    NOT_PERSISTED, PERSISTED, NOT_CALCULATED, CALCULATED;
}
EnumSet<ResultingState> errorsState = EnumSet.of(ResultingState.NOT_PERSISTED, ResultingState.NOT_CALCULATED);
Collection<ResultingState> results = new HashSet<>(phaseResults.values());
boolean containsAny = results.retainAll(errorsState) && results.size() > 0;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top