-
Enhancement
-
Resolution: Unresolved
-
P5
-
None
-
6
-
x86
-
windows_xp
A DESCRIPTION OF THE REQUEST :
According to its comments, the EnumSet class is () intended as a replacement for int-based bit flags, with sufficient space and time performance. Most of the standard operations are implemented, with the exception of a test that the two bit flags have at least one element in common (or, are disjoint). That is, I cannot replace the standard constructs:
((flag1 & flag2) != 0) // overlap in at least one position
((flag1 & flag2) == 0) // disjoint
with a method call that has bit flag efficiency.
JUSTIFICATION :
For code that requires high efficiency and has an enum with enough values, the lack of a high-speed disjoint check can be enough to disqualify the EnumSet and force use of bit flags.
The method seems simple enough to implement, and useful as a generic concept (about as useful as ContainsAll). For consistency, it could also be added to Collection/AbstractCollection with a generic implementation.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
public boolean containsAny(Collection<?> c) {
if (c instanceof EnumSet) {
return (((EnumSet)c).elements & this.elements) != 0;
} else {
Iterator<?> e = c.iterator();
while (e.hasNext())
if (contains(e.next()))
return true;
return false;
}
}
ACTUAL -
Existing workarounds are likely slower.
---------- BEGIN SOURCE ----------
// Allocate two sets of MyEnum
EnumSet<MyEnum> oneSet = EnumSet.of(V1, V3, V5, V7, V9, ...);
EnumSet<MyEnum> twoSet = EnumSet.complementOf(oneSet);
// Guaranteed true, but takes o(n^2) to determine
if(Collections.disjoint(oneSet, twoSet)) {
...
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
The workarounds in bug 6437213 give the required functionality, but without the efficiency gain possible with an EnumSet-specific implementation. The best one there is:
!Collections.disjoint(thisSet, otherSet)
It might be possible to enhance the Collections.disjoint() method to detect when both are EnumSets and use the faster comparison in that case, but that seems like a less desirable change.
According to its comments, the EnumSet class is () intended as a replacement for int-based bit flags, with sufficient space and time performance. Most of the standard operations are implemented, with the exception of a test that the two bit flags have at least one element in common (or, are disjoint). That is, I cannot replace the standard constructs:
((flag1 & flag2) != 0) // overlap in at least one position
((flag1 & flag2) == 0) // disjoint
with a method call that has bit flag efficiency.
JUSTIFICATION :
For code that requires high efficiency and has an enum with enough values, the lack of a high-speed disjoint check can be enough to disqualify the EnumSet and force use of bit flags.
The method seems simple enough to implement, and useful as a generic concept (about as useful as ContainsAll). For consistency, it could also be added to Collection/AbstractCollection with a generic implementation.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
public boolean containsAny(Collection<?> c) {
if (c instanceof EnumSet) {
return (((EnumSet)c).elements & this.elements) != 0;
} else {
Iterator<?> e = c.iterator();
while (e.hasNext())
if (contains(e.next()))
return true;
return false;
}
}
ACTUAL -
Existing workarounds are likely slower.
---------- BEGIN SOURCE ----------
// Allocate two sets of MyEnum
EnumSet<MyEnum> oneSet = EnumSet.of(V1, V3, V5, V7, V9, ...);
EnumSet<MyEnum> twoSet = EnumSet.complementOf(oneSet);
// Guaranteed true, but takes o(n^2) to determine
if(Collections.disjoint(oneSet, twoSet)) {
...
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
The workarounds in bug 6437213 give the required functionality, but without the efficiency gain possible with an EnumSet-specific implementation. The best one there is:
!Collections.disjoint(thisSet, otherSet)
It might be possible to enhance the Collections.disjoint() method to detect when both are EnumSets and use the faster comparison in that case, but that seems like a less desirable change.
- relates to
-
JDK-8313436 Add Collections.containsAny(), containsNone(), allMatch(), anyMatch(), noneMatch()
-
- Closed
-
-
JDK-6437213 Provide a new java.lang.EnumSet method "boolean containsAny(Collection<?> c)"
-
- Closed
-