Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6767177

Provide an efficient "boolean java.lang.EnumSet.containsAny(Collection<?> c)"

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Unresolved
    • Icon: P5 P5
    • None
    • 6
    • core-libs

      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.

            Unassigned Unassigned
            ndcosta Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Imported:
              Indexed: