[PATCH 1/1] RFC: Add a couple more trivial set methods to java.util.Collections

David M. Lloyd david.lloyd at redhat.com
Thu Dec 4 18:32:57 UTC 2008


Just a random thought I had.  Why not add methods to create two- or 
three-element sets in the same spirit as Set<T> singleton(T)?  The idea 
could be expanded beyond three elements but I think the initial comparisons 
would get too complex.

Also fixes a javadoc nit in singleton().

BTW, I'm sceptical about the claims within the javadoc for singleton() that 
the resultant set is serializable, as the field containing the element is 
final.

See patch below.

- DML

--

Index: tl/jdk/src/share/classes/java/util/Collections.java
===================================================================
--- tl/jdk/src/share/classes/java/util/Collections.java	Thu Dec 04 11:45:03 
CST 2008
+++ tl/jdk/src/share/classes/java/util/Collections.java	Thu Dec 04 11:45:03 
CST 2008
@@ -3241,8 +3241,9 @@
       * Returns an immutable set containing only the specified object.
       * The returned set is serializable.
       *
-     * @param o the sole object to be stored in the returned set.
-     * @return an immutable set containing only the specified object.
+     * @param o the sole object to be stored in the returned set
+     * @param <T> the element type
+     * @return an immutable set containing only the specified object
       */
      public static <T> Set<T> singleton(T o) {
          return new SingletonSet<T>(o);
@@ -3290,6 +3291,138 @@
      }

      /**
+     * Returns an immutable set containing only the specified objects.
+     * The returned set is serializable.
+     *
+     * @param one the first object to be stored in the returned set
+     * @param two the second object to be stored in the returned set
+     * @param <T> the element type
+     * @return an immutable set containing only the specified objects
+     */
+    public static <T> Set<T> set(T one, T two) {
+        if (eq(one, two)) {
+            return new SingletonSet<T>(one);
+        } else {
+            return new TwoSet<T>(one, two);
+        }
+    }
+
+    /**
+     * @serial include
+     */
+    private static class TwoSet<E>
+        extends AbstractSet<E>
+        implements Serializable
+    {
+        private static final long serialVersionUID = -839812055543945907L;
+
+        private final E one;
+        private final E two;
+
+        TwoSet(E one, E two) {
+            this.one = one;
+            this.two = two;
+        }
+
+        public Iterator<E> iterator() {
+            return new Iterator<E>() {
+                private int state;
+
+                public boolean hasNext() {
+                    return state < 2;
+                }
+
+                public E next() {
+                    switch (state) {
+                        case 0: try { return one; } finally { state++; }
+                        case 1: try { return two; } finally { state++; }
+                        default: throw new NoSuchElementException();
+                    }
+                }
+
+                public void remove() {
+                    throw new UnsupportedOperationException();
+                }
+            };
+        }
+
+        public int size() {return 2;}
+
+        public boolean contains(Object o) {return eq(o, one) || eq(o, two);}
+    }
+
+    /**
+     * Returns an immutable set containing only the specified objects.
+     * The returned set is serializable.
+     *
+     * @param one the first object to be stored in the returned set
+     * @param two the second object to be stored in the returned set
+     * @param three the third object to be stored in the returned set
+     * @param <T> the element type
+     * @return an immutable set containing only the specified objects
+     */
+    public static <T> Set<T> set(T one, T two, T three) {
+        final boolean oneTwo = eq(one, two);
+        final boolean twoThree = eq(two, three);
+        if (oneTwo && twoThree) {
+            return new SingletonSet<T>(one);
+        } else if (oneTwo && ! twoThree) {
+            return new TwoSet<T>(one, three);
+        } else if (twoThree && ! oneTwo || eq(one, three)) {
+            return new TwoSet<T>(one, two);
+        } else {
+            return new ThreeSet<T>(one, two, three);
+        }
+    }
+
+    /**
+     * @serial include
+     */
+    private static class ThreeSet<E>
+        extends AbstractSet<E>
+        implements Serializable
+    {
+        private static final long serialVersionUID = 832299003435439813L;
+
+        private final E one;
+        private final E two;
+        private final E three;
+
+        ThreeSet(E one, E two, E three) {
+            this.one = one;
+            this.two = two;
+            this.three = three;
+        }
+
+        public Iterator<E> iterator() {
+            return new Iterator<E>() {
+                private int state;
+
+                public boolean hasNext() {
+                    return state < 3;
+                }
+
+                public E next() {
+                    switch (state) {
+                        case 0: try { return one; } finally { state++; }
+                        case 1: try { return two; } finally { state++; }
+                        case 2: try { return three; } finally { state++; }
+                        default: throw new NoSuchElementException();
+                    }
+                }
+
+                public void remove() {
+                    throw new UnsupportedOperationException();
+                }
+            };
+        }
+
+        public int size() {return 3;}
+
+        public boolean contains(Object o) {return eq(o, one) || eq(o, two) 
|| eq(o, three);}
+    }
+
+    /**
       * Returns an immutable list containing only the specified object.
       * The returned list is serializable.
       *



More information about the core-libs-dev mailing list