Home | History | Annotate | Download | only in collect
      1 /*
      2  * Copyright (C) 2007 Google Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.common.collect;
     18 
     19 import com.google.common.annotations.GwtCompatible;
     20 import com.google.common.base.Predicate;
     21 import com.google.common.base.Predicates;
     22 import com.google.common.collect.Collections2.FilteredCollection;
     23 import com.google.common.primitives.Ints;
     24 
     25 import java.io.IOException;
     26 import java.io.ObjectInputStream;
     27 import java.io.Serializable;
     28 import java.util.AbstractSet;
     29 import java.util.Arrays;
     30 import java.util.Collection;
     31 import java.util.Collections;
     32 import java.util.Comparator;
     33 import java.util.EnumSet;
     34 import java.util.HashMap;
     35 import java.util.HashSet;
     36 import java.util.IdentityHashMap;
     37 import java.util.Iterator;
     38 import java.util.LinkedHashSet;
     39 import java.util.List;
     40 import java.util.Map;
     41 import java.util.NoSuchElementException;
     42 import java.util.Set;
     43 import java.util.SortedSet;
     44 import java.util.TreeMap;
     45 import java.util.TreeSet;
     46 
     47 import javax.annotation.Nullable;
     48 
     49 import static com.google.common.base.Preconditions.checkArgument;
     50 import static com.google.common.base.Preconditions.checkNotNull;
     51 
     52 /**
     53  * Static utility methods pertaining to {@link Set} instances. Also see this
     54  * class's counterparts {@link Lists} and {@link Maps}.
     55  *
     56  * @author Kevin Bourrillion
     57  * @author Jared Levy
     58  * @since 2010.01.04 <b>stable</b> (imported from Google Collections Library)
     59  */
     60 @GwtCompatible
     61 public final class Sets {
     62   private Sets() {}
     63 
     64   /**
     65    * Returns an immutable set instance containing the given enum elements.
     66    * Internally, the returned set will be backed by an {@link EnumSet}.
     67    *
     68    * <p>The iteration order of the returned set follows the enum's iteration
     69    * order, not the order in which the elements are provided to the method.
     70    *
     71    * @param anElement one of the elements the set should contain
     72    * @param otherElements the rest of the elements the set should contain
     73    * @return an immutable set containing those elements, minus duplicates
     74    */
     75   // http://code.google.com/p/google-web-toolkit/issues/detail?id=3028
     76   @GwtCompatible(serializable = true)
     77   public static <E extends Enum<E>> ImmutableSet<E> immutableEnumSet(
     78       E anElement, E... otherElements) {
     79     return new ImmutableEnumSet<E>(EnumSet.of(anElement, otherElements));
     80   }
     81 
     82   /**
     83    * Returns an immutable set instance containing the given enum elements.
     84    * Internally, the returned set will be backed by an {@link EnumSet}.
     85    *
     86    * <p>The iteration order of the returned set follows the enum's iteration
     87    * order, not the order in which the elements appear in the given collection.
     88    *
     89    * @param elements the elements, all of the same {@code enum} type, that the
     90    *     set should contain
     91    * @return an immutable set containing those elements, minus duplicates
     92    */
     93   // http://code.google.com/p/google-web-toolkit/issues/detail?id=3028
     94   @GwtCompatible(serializable = true)
     95   public static <E extends Enum<E>> ImmutableSet<E> immutableEnumSet(
     96       Iterable<E> elements) {
     97     Iterator<E> iterator = elements.iterator();
     98     if (!iterator.hasNext()) {
     99       return ImmutableSet.of();
    100     }
    101     if (elements instanceof EnumSet) {
    102       EnumSet<E> enumSetClone = EnumSet.copyOf((EnumSet<E>) elements);
    103       return new ImmutableEnumSet<E>(enumSetClone);
    104     }
    105     E first = iterator.next();
    106     EnumSet<E> set = EnumSet.of(first);
    107     while (iterator.hasNext()) {
    108       set.add(iterator.next());
    109     }
    110     return new ImmutableEnumSet<E>(set);
    111   }
    112 
    113   /**
    114    * Returns a new {@code EnumSet} instance containing the given elements.
    115    * Unlike {@link EnumSet#copyOf(Collection)}, this method does not produce an
    116    * exception on an empty collection, and it may be called on any iterable, not
    117    * just a {@code Collection}.
    118    */
    119   public static <E extends Enum<E>> EnumSet<E> newEnumSet(Iterable<E> iterable,
    120       Class<E> elementType) {
    121     /*
    122      * TODO: noneOf() and addAll() will both throw NullPointerExceptions when
    123      * appropriate. However, NullPointerTester will fail on this method because
    124      * it passes in Class.class instead of an enum type. This means that, when
    125      * iterable is null but elementType is not, noneOf() will throw a
    126      * ClassCastException before addAll() has a chance to throw a
    127      * NullPointerException. NullPointerTester considers this a failure.
    128      * Ideally the test would be fixed, but it would require a special case for
    129      * Class<E> where E extends Enum. Until that happens (if ever), leave
    130      * checkNotNull() here. For now, contemplate the irony that checking
    131      * elementType, the problem argument, is harmful, while checking iterable,
    132      * the innocent bystander, is effective.
    133      */
    134     checkNotNull(iterable);
    135     EnumSet<E> set = EnumSet.noneOf(elementType);
    136     Iterables.addAll(set, iterable);
    137     return set;
    138   }
    139 
    140   // HashSet
    141 
    142   /**
    143    * Creates a <i>mutable</i>, empty {@code HashSet} instance.
    144    *
    145    * <p><b>Note:</b> if mutability is not required, use {@link
    146    * ImmutableSet#of()} instead.
    147    *
    148    * <p><b>Note:</b> if {@code E} is an {@link Enum} type, use {@link
    149    * EnumSet#noneOf} instead.
    150    *
    151    * @return a new, empty {@code HashSet}
    152    */
    153   public static <E> HashSet<E> newHashSet() {
    154     return new HashSet<E>();
    155   }
    156 
    157   /**
    158    * Creates a <i>mutable</i> {@code HashSet} instance containing the given
    159    * elements in unspecified order.
    160    *
    161    * <p><b>Note:</b> if mutability is not required and the elements are
    162    * non-null, use {@link ImmutableSet#of(Object[])} instead.
    163    *
    164    * <p><b>Note:</b> if {@code E} is an {@link Enum} type, use {@link
    165    * EnumSet#of(Enum, Enum[])} instead.
    166    *
    167    * @param elements the elements that the set should contain
    168    * @return a new {@code HashSet} containing those elements (minus duplicates)
    169    */
    170   public static <E> HashSet<E> newHashSet(E... elements) {
    171     int capacity = Maps.capacity(elements.length);
    172     HashSet<E> set = new HashSet<E>(capacity);
    173     Collections.addAll(set, elements);
    174     return set;
    175   }
    176 
    177   /**
    178    * Creates an empty {@code HashSet} instance with enough capacity to hold the
    179    * specified number of elements without rehashing.
    180    *
    181    * @param expectedSize the expected size
    182    * @return a new, empty {@code HashSet} with enough capacity to hold {@code
    183    *     expectedSize} elements without rehashing
    184    * @throws IllegalArgumentException if {@code expectedSize} is negative
    185    */
    186   public static <E> HashSet<E> newHashSetWithExpectedSize(int expectedSize) {
    187     return new HashSet<E>(Maps.capacity(expectedSize));
    188   }
    189 
    190   /**
    191    * Creates a <i>mutable</i> {@code HashSet} instance containing the given
    192    * elements in unspecified order.
    193    *
    194    * <p><b>Note:</b> if mutability is not required and the elements are
    195    * non-null, use {@link ImmutableSet#copyOf(Iterable)} instead.
    196    *
    197    * <p><b>Note:</b> if {@code E} is an {@link Enum} type, use
    198    * {@link #newEnumSet(Iterable, Class)} instead.
    199    *
    200    * @param elements the elements that the set should contain
    201    * @return a new {@code HashSet} containing those elements (minus duplicates)
    202    */
    203   public static <E> HashSet<E> newHashSet(Iterable<? extends E> elements) {
    204     if (elements instanceof Collection) {
    205       @SuppressWarnings("unchecked")
    206       Collection<? extends E> collection = (Collection<? extends E>) elements;
    207       return new HashSet<E>(collection);
    208     } else {
    209       return newHashSet(elements.iterator());
    210     }
    211   }
    212 
    213   /**
    214    * Creates a <i>mutable</i> {@code HashSet} instance containing the given
    215    * elements in unspecified order.
    216    *
    217    * <p><b>Note:</b> if mutability is not required and the elements are
    218    * non-null, use {@link ImmutableSet#copyOf(Iterable)} instead.
    219    *
    220    * <p><b>Note:</b> if {@code E} is an {@link Enum} type, you should create an
    221    * {@link EnumSet} instead.
    222    *
    223    * @param elements the elements that the set should contain
    224    * @return a new {@code HashSet} containing those elements (minus duplicates)
    225    */
    226   public static <E> HashSet<E> newHashSet(Iterator<? extends E> elements) {
    227     HashSet<E> set = newHashSet();
    228     while (elements.hasNext()) {
    229       set.add(elements.next());
    230     }
    231     return set;
    232   }
    233 
    234   // LinkedHashSet
    235 
    236   /**
    237    * Creates a <i>mutable</i>, empty {@code LinkedHashSet} instance.
    238    *
    239    * <p><b>Note:</b> if mutability is not required, use {@link
    240    * ImmutableSet#of()} instead.
    241    *
    242    * @return a new, empty {@code LinkedHashSet}
    243    */
    244   public static <E> LinkedHashSet<E> newLinkedHashSet() {
    245     return new LinkedHashSet<E>();
    246   }
    247 
    248   /**
    249    * Creates a <i>mutable</i> {@code LinkedHashSet} instance containing the
    250    * given elements in order.
    251    *
    252    * <p><b>Note:</b> if mutability is not required and the elements are
    253    * non-null, use {@link ImmutableSet#copyOf(Iterable)} instead.
    254    *
    255    * @param elements the elements that the set should contain, in order
    256    * @return a new {@code LinkedHashSet} containing those elements (minus
    257    *     duplicates)
    258    */
    259   public static <E> LinkedHashSet<E> newLinkedHashSet(
    260       Iterable<? extends E> elements) {
    261     if (elements instanceof Collection) {
    262       @SuppressWarnings("unchecked")
    263       Collection<? extends E> collection = (Collection<? extends E>) elements;
    264       return new LinkedHashSet<E>(collection);
    265     } else {
    266       LinkedHashSet<E> set = newLinkedHashSet();
    267       for (E element : elements) {
    268         set.add(element);
    269       }
    270       return set;
    271     }
    272   }
    273 
    274   // TreeSet
    275 
    276   /**
    277    * Creates a <i>mutable</i>, empty {@code TreeSet} instance sorted by the
    278    * natural sort ordering of its elements.
    279    *
    280    * <p><b>Note:</b> if mutability is not required, use {@link
    281    * ImmutableSortedSet#of()} instead.
    282    *
    283    * @return a new, empty {@code TreeSet}
    284    */
    285   @SuppressWarnings("unchecked")  // allow ungenerified Comparable types
    286   public static <E extends Comparable> TreeSet<E> newTreeSet() {
    287     return new TreeSet<E>();
    288   }
    289 
    290   /**
    291    * Creates a <i>mutable</i> {@code TreeSet} instance containing the given
    292    * elements sorted by their natural ordering.
    293    *
    294    * <p><b>Note:</b> if mutability is not required, use {@link
    295    * ImmutableSortedSet#copyOf(Iterable)} instead.
    296    *
    297    * <p><b>Note:</b> If {@code elements} is a {@code SortedSet} with an explicit
    298    * comparator, this method has different behavior than
    299    * {@link TreeSet#TreeSet(SortedSet)}, which returns a {@code TreeSet} with
    300    * that comparator.
    301    *
    302    * @param elements the elements that the set should contain
    303    * @return a new {@code TreeSet} containing those elements (minus duplicates)
    304    */
    305   @SuppressWarnings("unchecked")  // allow ungenerified Comparable types
    306   public static <E extends Comparable> TreeSet<E> newTreeSet(
    307       Iterable<? extends E> elements) {
    308     TreeSet<E> set = newTreeSet();
    309     for (E element : elements) {
    310       set.add(element);
    311     }
    312     return set;
    313   }
    314 
    315   /**
    316    * Creates a <i>mutable</i>, empty {@code TreeSet} instance with the given
    317    * comparator.
    318    *
    319    * <p><b>Note:</b> if mutability is not required, use {@code
    320    * ImmutableSortedSet.orderedBy(comparator).build()} instead.
    321    *
    322    * @param comparator the comparator to use to sort the set
    323    * @return a new, empty {@code TreeSet}
    324    * @throws NullPointerException if {@code comparator} is null
    325    */
    326   public static <E> TreeSet<E> newTreeSet(Comparator<? super E> comparator) {
    327     return new TreeSet<E>(checkNotNull(comparator));
    328   }
    329 
    330   /**
    331    * Creates an {@code EnumSet} consisting of all enum values that are not in
    332    * the specified collection. If the collection is an {@link EnumSet}, this
    333    * method has the same behavior as {@link EnumSet#complementOf}. Otherwise,
    334    * the specified collection must contain at least one element, in order to
    335    * determine the element type. If the collection could be empty, use
    336    * {@link #complementOf(Collection, Class)} instead of this method.
    337    *
    338    * @param collection the collection whose complement should be stored in the
    339    *     enum set
    340    * @return a new, modifiable {@code EnumSet} containing all values of the enum
    341    *     that aren't present in the given collection
    342    * @throws IllegalArgumentException if {@code collection} is not an
    343    *     {@code EnumSet} instance and contains no elements
    344    */
    345   public static <E extends Enum<E>> EnumSet<E> complementOf(
    346       Collection<E> collection) {
    347     if (collection instanceof EnumSet) {
    348       return EnumSet.complementOf((EnumSet<E>) collection);
    349     }
    350     checkArgument(!collection.isEmpty(),
    351         "collection is empty; use the other version of this method");
    352     Class<E> type = collection.iterator().next().getDeclaringClass();
    353     return makeComplementByHand(collection, type);
    354   }
    355 
    356   /**
    357    * Creates an {@code EnumSet} consisting of all enum values that are not in
    358    * the specified collection. This is equivalent to
    359    * {@link EnumSet#complementOf}, but can act on any input collection, as long
    360    * as the elements are of enum type.
    361    *
    362    * @param collection the collection whose complement should be stored in the
    363    *     {@code EnumSet}
    364    * @param type the type of the elements in the set
    365    * @return a new, modifiable {@code EnumSet} initially containing all the
    366    *     values of the enum not present in the given collection
    367    */
    368   public static <E extends Enum<E>> EnumSet<E> complementOf(
    369       Collection<E> collection, Class<E> type) {
    370     checkNotNull(collection);
    371     return (collection instanceof EnumSet)
    372         ? EnumSet.complementOf((EnumSet<E>) collection)
    373         : makeComplementByHand(collection, type);
    374   }
    375 
    376   private static <E extends Enum<E>> EnumSet<E> makeComplementByHand(
    377       Collection<E> collection, Class<E> type) {
    378     EnumSet<E> result = EnumSet.allOf(type);
    379     result.removeAll(collection);
    380     return result;
    381   }
    382 
    383   /*
    384    * Regarding newSetForMap() and SetFromMap:
    385    *
    386    * Written by Doug Lea with assistance from members of JCP JSR-166
    387    * Expert Group and released to the public domain, as explained at
    388    * http://creativecommons.org/licenses/publicdomain
    389    */
    390 
    391   /**
    392    * Returns a set backed by the specified map. The resulting set displays
    393    * the same ordering, concurrency, and performance characteristics as the
    394    * backing map. In essence, this factory method provides a {@link Set}
    395    * implementation corresponding to any {@link Map} implementation. There is no
    396    * need to use this method on a {@link Map} implementation that already has a
    397    * corresponding {@link Set} implementation (such as {@link HashMap} or
    398    * {@link TreeMap}).
    399    *
    400    * <p>Each method invocation on the set returned by this method results in
    401    * exactly one method invocation on the backing map or its <tt>keySet</tt>
    402    * view, with one exception. The <tt>addAll</tt> method is implemented as a
    403    * sequence of <tt>put</tt> invocations on the backing map.
    404    *
    405    * <p>The specified map must be empty at the time this method is invoked,
    406    * and should not be accessed directly after this method returns. These
    407    * conditions are ensured if the map is created empty, passed directly
    408    * to this method, and no reference to the map is retained, as illustrated
    409    * in the following code fragment: <pre>  {@code
    410    *
    411    *  Set<Object> identityHashSet = Sets.newSetFromMap(
    412    *      new IdentityHashMap<Object, Boolean>());}</pre>
    413    *
    414    * This method has the same behavior as the JDK 6 method
    415    * {@code Collections.newSetFromMap()}. The returned set is serializable if
    416    * the backing map is.
    417    *
    418    * @param map the backing map
    419    * @return the set backed by the map
    420    * @throws IllegalArgumentException if <tt>map</tt> is not empty
    421    */
    422   public static <E> Set<E> newSetFromMap(Map<E, Boolean> map) {
    423     return new SetFromMap<E>(map);
    424   }
    425 
    426   private static class SetFromMap<E> extends AbstractSet<E>
    427       implements Set<E>, Serializable {
    428     private final Map<E, Boolean> m; // The backing map
    429     private transient Set<E> s; // Its keySet
    430 
    431     SetFromMap(Map<E, Boolean> map) {
    432       checkArgument(map.isEmpty(), "Map is non-empty");
    433       m = map;
    434       s = map.keySet();
    435     }
    436 
    437     @Override public void clear() {
    438       m.clear();
    439     }
    440     @Override public int size() {
    441       return m.size();
    442     }
    443     @Override public boolean isEmpty() {
    444       return m.isEmpty();
    445     }
    446     @Override public boolean contains(Object o) {
    447       return m.containsKey(o);
    448     }
    449     @Override public boolean remove(Object o) {
    450       return m.remove(o) != null;
    451     }
    452     @Override public boolean add(E e) {
    453       return m.put(e, Boolean.TRUE) == null;
    454     }
    455     @Override public Iterator<E> iterator() {
    456       return s.iterator();
    457     }
    458     @Override public Object[] toArray() {
    459       return s.toArray();
    460     }
    461     @Override public <T> T[] toArray(T[] a) {
    462       return s.toArray(a);
    463     }
    464     @Override public String toString() {
    465       return s.toString();
    466     }
    467     @Override public int hashCode() {
    468       return s.hashCode();
    469     }
    470     @Override public boolean equals(@Nullable Object object) {
    471       return this == object || this.s.equals(object);
    472     }
    473     @Override public boolean containsAll(Collection<?> c) {
    474       return s.containsAll(c);
    475     }
    476     @Override public boolean removeAll(Collection<?> c) {
    477       return s.removeAll(c);
    478     }
    479     @Override public boolean retainAll(Collection<?> c) {
    480       return s.retainAll(c);
    481     }
    482 
    483     // addAll is the only inherited implementation
    484 
    485     private static final long serialVersionUID = 0;
    486 
    487     private void readObject(ObjectInputStream stream)
    488         throws IOException, ClassNotFoundException {
    489       stream.defaultReadObject();
    490       s = m.keySet();
    491     }
    492   }
    493 
    494   /**
    495    * An unmodifiable view of a set which may be backed by other sets; this view
    496    * will change as the backing sets do. Contains methods to copy the data into
    497    * a new set which will then remain stable. There is usually no reason to
    498    * retain a reference of type {@code SetView}; typically, you either use it
    499    * as a plain {@link Set}, or immediately invoke {@link #immutableCopy} or
    500    * {@link #copyInto} and forget the {@code SetView} itself.
    501    */
    502   public abstract static class SetView<E> extends AbstractSet<E> {
    503     private SetView() {} // no subclasses but our own
    504 
    505     /**
    506      * Returns an immutable copy of the current contents of this set view.
    507      * Does not support null elements.
    508      *
    509      * <p><b>Warning:</b> this may have unexpected results if a backing set of
    510      * this view uses a nonstandard notion of equivalence, for example if it is
    511      * a {@link TreeSet} using a comparator that is inconsistent with {@link
    512      * Object#equals(Object)}.
    513      */
    514     public ImmutableSet<E> immutableCopy() {
    515       return ImmutableSet.copyOf(this);
    516     }
    517 
    518     /**
    519      * Copies the current contents of this set view into an existing set. This
    520      * method has equivalent behavior to {@code set.addAll(this)}, assuming that
    521      * all the sets involved are based on the same notion of equivalence.
    522      *
    523      * @return a reference to {@code set}, for convenience
    524      */
    525     // Note: S should logically extend Set<? super E> but can't due to either
    526     // some javac bug or some weirdness in the spec, not sure which.
    527     public <S extends Set<E>> S copyInto(S set) {
    528       set.addAll(this);
    529       return set;
    530     }
    531   }
    532 
    533   /**
    534    * Returns an unmodifiable <b>view</b> of the union of two sets. The returned
    535    * set contains all elements that are contained in either backing set.
    536    * Iterating over the returned set iterates first over all the elements of
    537    * {@code set1}, then over each element of {@code set2}, in order, that is not
    538    * contained in {@code set1}.
    539    *
    540    * <p>Results are undefined if {@code set1} and {@code set2} are sets based on
    541    * different equivalence relations (as {@link HashSet}, {@link TreeSet}, and
    542    * the {@link Map#keySet} of an {@link IdentityHashMap} all are).
    543    *
    544    * <p><b>Note:</b> The returned view performs better when {@code set1} is the
    545    * smaller of the two sets. If you have reason to believe one of your sets
    546    * will generally be smaller than the other, pass it first.
    547    */
    548   public static <E> SetView<E> union(
    549       final Set<? extends E> set1, final Set<? extends E> set2) {
    550     checkNotNull(set1, "set1");
    551     checkNotNull(set2, "set2");
    552 
    553     // TODO: once we have OrderedIterators, check if these are compatible
    554     // sorted sets and use that instead if so
    555 
    556     final Set<? extends E> set2minus1 = difference(set2, set1);
    557 
    558     return new SetView<E>() {
    559       @Override public int size() {
    560         return set1.size() + set2minus1.size();
    561       }
    562       @Override public boolean isEmpty() {
    563         return set1.isEmpty() && set2.isEmpty();
    564       }
    565       @Override public Iterator<E> iterator() {
    566         return Iterators.unmodifiableIterator(
    567             Iterators.concat(set1.iterator(), set2minus1.iterator()));
    568       }
    569       @Override public boolean contains(Object object) {
    570         return set1.contains(object) || set2.contains(object);
    571       }
    572       @Override public <S extends Set<E>> S copyInto(S set) {
    573         set.addAll(set1);
    574         set.addAll(set2);
    575         return set;
    576       }
    577       @Override public ImmutableSet<E> immutableCopy() {
    578         return new ImmutableSet.Builder<E>()
    579             .addAll(set1).addAll(set2).build();
    580       }
    581     };
    582   }
    583 
    584   /**
    585    * Returns an unmodifiable <b>view</b> of the intersection of two sets. The
    586    * returned set contains all elements that are contained by both backing sets.
    587    * The iteration order of the returned set matches that of {@code set1}.
    588    *
    589    * <p>Results are undefined if {@code set1} and {@code set2} are sets based
    590    * on different equivalence relations (as {@code HashSet}, {@code TreeSet},
    591    * and the keySet of an {@code IdentityHashMap} all are).
    592    *
    593    * <p><b>Note:</b> The returned view performs slightly better when {@code
    594    * set1} is the smaller of the two sets. If you have reason to believe one of
    595    * your sets will generally be smaller than the other, pass it first.
    596    * Unfortunately, since this method sets the generic type of the returned set
    597    * based on the type of the first set passed, this could in rare cases force
    598    * you to make a cast, for example: <pre>  {@code
    599    *
    600    *  Set<Object> aFewBadObjects = ...
    601    *  Set<String> manyBadStrings = ...
    602    *
    603    *  // impossible for a non-String to be in the intersection
    604    *  SuppressWarnings("unchecked")
    605    *  Set<String> badStrings = (Set) Sets.intersection(
    606    *      aFewBadObjects, manyBadStrings);}</pre>
    607    *
    608    * This is unfortunate, but should come up only very rarely.
    609    */
    610   public static <E> SetView<E> intersection(
    611       final Set<E> set1, final Set<?> set2) {
    612     checkNotNull(set1, "set1");
    613     checkNotNull(set2, "set2");
    614 
    615     // TODO: once we have OrderedIterators, check if these are compatible
    616     // sorted sets and use that instead if so
    617 
    618     final Predicate<Object> inSet2 = Predicates.in(set2);
    619     return new SetView<E>() {
    620       @Override public Iterator<E> iterator() {
    621         return Iterators.filter(set1.iterator(), inSet2);
    622       }
    623       @Override public int size() {
    624         return Iterators.size(iterator());
    625       }
    626       @Override public boolean isEmpty() {
    627         return !iterator().hasNext();
    628       }
    629       @Override public boolean contains(Object object) {
    630         return set1.contains(object) && set2.contains(object);
    631       }
    632       @Override public boolean containsAll(Collection<?> collection) {
    633         return set1.containsAll(collection)
    634             && set2.containsAll(collection);
    635       }
    636     };
    637   }
    638 
    639   /**
    640    * Returns an unmodifiable <b>view</b> of the difference of two sets. The
    641    * returned set contains all elements that are contained by {@code set1} and
    642    * not contained by {@code set2}. {@code set2} may also contain elements not
    643    * present in {@code set1}; these are simply ignored. The iteration order of
    644    * the returned set matches that of {@code set1}.
    645    *
    646    * <p>Results are undefined if {@code set1} and {@code set2} are sets based
    647    * on different equivalence relations (as {@code HashSet}, {@code TreeSet},
    648    * and the keySet of an {@code IdentityHashMap} all are).
    649    */
    650   public static <E> SetView<E> difference(
    651       final Set<E> set1, final Set<?> set2) {
    652     checkNotNull(set1, "set1");
    653     checkNotNull(set2, "set2");
    654 
    655     // TODO: once we have OrderedIterators, check if these are compatible
    656     // sorted sets and use that instead if so
    657 
    658     final Predicate<Object> notInSet2 = Predicates.not(Predicates.in(set2));
    659     return new SetView<E>() {
    660       @Override public Iterator<E> iterator() {
    661         return Iterators.filter(set1.iterator(), notInSet2);
    662       }
    663       @Override public int size() {
    664         return Iterators.size(iterator());
    665       }
    666       @Override public boolean isEmpty() {
    667         return set2.containsAll(set1);
    668       }
    669       @Override public boolean contains(Object element) {
    670         return set1.contains(element) && !set2.contains(element);
    671       }
    672     };
    673   }
    674 
    675   /**
    676    * Returns the elements of {@code unfiltered} that satisfy a predicate. The
    677    * returned set is a live view of {@code unfiltered}; changes to one affect
    678    * the other.
    679    *
    680    * <p>The resulting set's iterator does not support {@code remove()}, but all
    681    * other set methods are supported. The set's {@code add()} and
    682    * {@code addAll()} methods throw an {@link IllegalArgumentException} if an
    683    * element that doesn't satisfy the predicate is provided. When methods such
    684    * as {@code removeAll()} and {@code clear()} are called on the filtered set,
    685    * only elements that satisfy the filter will be removed from the underlying
    686    * collection.
    687    *
    688    * <p>The returned set isn't threadsafe or serializable, even if
    689    * {@code unfiltered} is.
    690    *
    691    * <p>Many of the filtered set's methods, such as {@code size()}, iterate
    692    * across every element in the underlying set and determine which elements
    693    * satisfy the filter. When a live view is <i>not</i> needed, it may be faster
    694    * to copy {@code Iterables.filter(unfiltered, predicate)} and use the copy.
    695    */
    696   public static <E> Set<E> filter(
    697       Set<E> unfiltered, Predicate<? super E> predicate) {
    698     if (unfiltered instanceof FilteredSet) {
    699       // Support clear(), removeAll(), and retainAll() when filtering a filtered
    700       // collection.
    701       FilteredSet<E> filtered = (FilteredSet<E>) unfiltered;
    702       Predicate<E> combinedPredicate
    703           = Predicates.<E>and(filtered.predicate, predicate);
    704       return new FilteredSet<E>(
    705           (Set<E>) filtered.unfiltered, combinedPredicate);
    706     }
    707 
    708     return new FilteredSet<E>(
    709         checkNotNull(unfiltered), checkNotNull(predicate));
    710   }
    711 
    712   private static class FilteredSet<E> extends FilteredCollection<E>
    713       implements Set<E> {
    714     FilteredSet(Set<E> unfiltered, Predicate<? super E> predicate) {
    715       super(unfiltered, predicate);
    716     }
    717 
    718     @Override public boolean equals(@Nullable Object object) {
    719       return Collections2.setEquals(this, object);
    720     }
    721 
    722     @Override public int hashCode() {
    723       return hashCodeImpl(this);
    724     }
    725   }
    726 
    727   /**
    728    * Returns every possible list that can be formed by choosing one element
    729    * from each of the given sets in order; the "n-ary
    730    * <a href="http://en.wikipedia.org/wiki/Cartesian_product">Cartesian
    731    * product</a>" of the sets. For example: <pre class="code">   {@code
    732    *
    733    *   cartesianProduct(ImmutableList.of(
    734    *       ImmutableSet.of(1, 2),
    735    *       ImmutableSet.of("A", "B", "C")))}</pre>
    736    *
    737    * returns a set containing six lists:
    738    *
    739    * <ul>
    740    * <li>{@code ImmutableList.of(1, "A")}
    741    * <li>{@code ImmutableList.of(1, "B")}
    742    * <li>{@code ImmutableList.of(1, "C")}
    743    * <li>{@code ImmutableList.of(2, "A")}
    744    * <li>{@code ImmutableList.of(2, "B")}
    745    * <li>{@code ImmutableList.of(2, "C")}
    746    * </ul>
    747    *
    748    * The order in which these lists are returned is not guaranteed, however the
    749    * position of an element inside a tuple always corresponds to the position of
    750    * the set from which it came in the input list. Note that if any input set is
    751    * empty, the Cartesian product will also be empty. If no sets at all are
    752    * provided (an empty list), the resulting Cartesian product has one element,
    753    * an empty list (counter-intuitive, but mathematically consistent).
    754    *
    755    * @param sets the sets to choose elements from, in the order that
    756    *     the elements chosen from those sets should appear in the resulting
    757    *     lists
    758    * @param <B> any common base class shared by all axes (often just {@link
    759    *     Object})
    760    * @return the Cartesian product, as an immutable set containing immutable
    761    *     lists
    762    * @throws NullPointerException if {@code sets}, any one of the {@code sets},
    763    *     or any element of a provided set is null
    764    * @since 2010.01.04 <b>tentative</b>
    765    */
    766   public static <B> Set<List<B>> cartesianProduct(
    767       List<? extends Set<? extends B>> sets) {
    768     CartesianSet<B> cartesianSet = new CartesianSet<B>(sets);
    769     return cartesianSet.isEmpty() ? ImmutableSet.<List<B>>of() : cartesianSet;
    770   }
    771 
    772   /**
    773    * Returns every possible list that can be formed by choosing one element
    774    * from each of the given sets in order; the "n-ary
    775    * <a href="http://en.wikipedia.org/wiki/Cartesian_product">Cartesian
    776    * product</a>" of the sets. For example: <pre class="code">   {@code
    777    *
    778    *   cartesianProduct(
    779    *       ImmutableSet.of(1, 2),
    780    *       ImmutableSet.of("A", "B", "C"))}</pre>
    781    *
    782    * returns a set containing six lists:
    783    w
    784    * <ul>
    785    * <li>{@code ImmutableList.of(1, "A")}
    786    * <li>{@code ImmutableList.of(1, "B")}
    787    * <li>{@code ImmutableList.of(1, "C")}
    788    * <li>{@code ImmutableList.of(2, "A")}
    789    * <li>{@code ImmutableList.of(2, "B")}
    790    * <li>{@code ImmutableList.of(2, "C")}
    791    * </ul>
    792    *
    793    * The order in which these lists are returned is not guaranteed, however the
    794    * position of an element inside a tuple always corresponds to the position of
    795    * the set from which it came in the input list. Note that if any input set is
    796    * empty, the Cartesian product will also be empty. If no sets at all are
    797    * provided, the resulting Cartesian product has one element, an empty list
    798    * (counter-intuitive, but mathematically consistent).
    799    *
    800    * @param sets the sets to choose elements from, in the order that
    801    *     the elements chosen from those sets should appear in the resulting
    802    *     lists
    803    * @param <B> any common base class shared by all axes (often just {@link
    804    *     Object})
    805    * @return the Cartesian product, as an immutable set containing immutable
    806    *     lists
    807    * @throws NullPointerException if {@code sets}, any one of the {@code sets},
    808    *     or any element of a provided set is null
    809    * @since 2010.01.04 <b>tentative</b>
    810    */
    811   public static <B> Set<List<B>> cartesianProduct(
    812       Set<? extends B>... sets) {
    813     return cartesianProduct(Arrays.asList(sets));
    814   }
    815 
    816   private static class CartesianSet<B> extends AbstractSet<List<B>> {
    817     final ImmutableList<Axis> axes;
    818     final int size;
    819 
    820     CartesianSet(List<? extends Set<? extends B>> sets) {
    821       long dividend = 1;
    822       ImmutableList.Builder<Axis> builder = ImmutableList.builder();
    823       for (Set<? extends B> set : sets) {
    824         Axis axis = new Axis(set, (int) dividend); // check overflow at end
    825         builder.add(axis);
    826         dividend *= axis.size();
    827       }
    828       this.axes = builder.build();
    829       size = Ints.checkedCast(dividend);
    830     }
    831 
    832     @Override public int size() {
    833       return size;
    834     }
    835 
    836     @Override public UnmodifiableIterator<List<B>> iterator() {
    837       return new UnmodifiableIterator<List<B>>() {
    838         int index;
    839 
    840         public boolean hasNext() {
    841           return index < size;
    842         }
    843 
    844         public List<B> next() {
    845           if (!hasNext()) {
    846             throw new NoSuchElementException();
    847           }
    848 
    849           Object[] tuple = new Object[axes.size()];
    850           for (int i = 0 ; i < tuple.length; i++) {
    851             tuple[i] = axes.get(i).getForIndex(index);
    852           }
    853           index++;
    854 
    855           @SuppressWarnings("unchecked") // only B's are put in here
    856           List<B> result = (ImmutableList<B>) ImmutableList.of(tuple);
    857           return result;
    858         }
    859       };
    860     }
    861 
    862     @Override public boolean contains(Object element) {
    863       if (!(element instanceof List<?>)) {
    864         return false;
    865       }
    866       List<?> tuple = (List<?>) element;
    867       int dimensions = axes.size();
    868       if (tuple.size() != dimensions) {
    869         return false;
    870       }
    871       for (int i = 0; i < dimensions; i++) {
    872         if (!axes.get(i).contains(tuple.get(i))) {
    873           return false;
    874         }
    875       }
    876       return true;
    877     }
    878 
    879     @Override public boolean equals(@Nullable Object object) {
    880       // Warning: this is broken if size() == 0, so it is critical that we
    881       // substitute an empty ImmutableSet to the user in place of this
    882       if (object instanceof CartesianSet<?>) {
    883         CartesianSet<?> that = (CartesianSet) object;
    884         return this.axes.equals(that.axes);
    885       }
    886       return super.equals(object);
    887     }
    888 
    889     @Override public int hashCode() {
    890       // Warning: this is broken if size() == 0, so it is critical that we
    891       // substitute an empty ImmutableSet to the user in place of this
    892 
    893       // It's a weird formula, but tests prove it works.
    894       int adjust = size - 1;
    895       for (int i = 0; i < axes.size(); i++) {
    896         adjust *= 31;
    897       }
    898       return axes.hashCode() + adjust;
    899     }
    900 
    901     private class Axis {
    902       final ImmutableSet<? extends B> choices;
    903       final int dividend;
    904 
    905       Axis(Set<? extends B> set, int dividend) {
    906         choices = ImmutableSet.copyOf(set);
    907         this.dividend = dividend;
    908       }
    909 
    910       int size() {
    911         return choices.size();
    912       }
    913 
    914       B getForIndex(int index) {
    915         return choices.asList().get(index / dividend % size());
    916       }
    917 
    918       boolean contains(Object target) {
    919         return choices.contains(target);
    920       }
    921 
    922       @Override public boolean equals(Object obj) {
    923         if (obj instanceof CartesianSet.Axis) {
    924           CartesianSet.Axis that = (CartesianSet.Axis) obj;
    925           return this.choices.equals(that.choices);
    926           // dividends must be equal or we wouldn't have gotten this far
    927         }
    928         return false;
    929       }
    930 
    931       @Override public int hashCode() {
    932         // an opportunistic formula chosen because it happens to make
    933         // CartesianSet.hashCode() work!
    934         return size / choices.size() * choices.hashCode();
    935       }
    936     }
    937   }
    938 
    939   /**
    940    * Calculates and returns the hash code of {@code s}.
    941    */
    942   static int hashCodeImpl(Set<?> s) {
    943     int hashCode = 0;
    944     for (Object o : s) {
    945       hashCode += o != null ? o.hashCode() : 0;
    946     }
    947     return hashCode;
    948   }
    949 }
    950