Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
    * Copyright (C) 2007 The Guava Authors
    *
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
    * You may obtain a copy of the License at
    *
    * http://www.apache.org/licenses/LICENSE-2.0
    *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package com.google.common.collect;
  
  import static com.google.common.base.Preconditions.checkArgument;
  import static com.google.common.base.Preconditions.checkNotNull;
  import static com.google.common.collect.CollectPreconditions.checkNonnegative;
  import static com.google.common.collect.CollectPreconditions.checkRemove;
  
  
  import java.util.List;
  import java.util.Set;
  
Provides static utility methods for creating and working with Multiset instances.

See the Guava User Guide article on Multisets.

Author(s):
Kevin Bourrillion
Mike Bostock
Louis Wasserman
Since:
2.0 (imported from Google Collections Library)
  
  public final class Multisets {
    private Multisets() {}

  
Returns an unmodifiable view of the specified multiset. Query operations on the returned multiset "read through" to the specified multiset, and attempts to modify the returned multiset result in an java.lang.UnsupportedOperationException.

The returned multiset will be serializable if the specified multiset is serializable.

Parameters:
multiset the multiset for which an unmodifiable view is to be generated
Returns:
an unmodifiable view of the multiset
  
    public static <E> Multiset<E> unmodifiableMultiset(
        Multiset<? extends E> multiset) {
      if (multiset instanceof UnmodifiableMultiset ||
          multiset instanceof ImmutableMultiset) {
        // Since it's unmodifiable, the covariant cast is safe
        @SuppressWarnings("unchecked")
        Multiset<E> result = (Multiset<E>) multiset;
        return result;
      }
      return new UnmodifiableMultiset<E>(checkNotNull(multiset));
    }

  
Simply returns its argument.

Deprecated:
no need to use this
Since:
10.0
  
    @Deprecated public static <E> Multiset<E> unmodifiableMultiset(
        ImmutableMultiset<E> multiset) {
      return checkNotNull(multiset);
    }
  
    static class UnmodifiableMultiset<E>
        extends ForwardingMultiset<E> implements Serializable {
      final Multiset<? extends E> delegate;
  
      UnmodifiableMultiset(Multiset<? extends E> delegate) {
       this. = delegate;
     }
 
     @SuppressWarnings("unchecked")
     @Override protected Multiset<E> delegate() {
       // This is safe because all non-covariant methods are overriden
       return (Multiset<E>) ;
     }
 
     transient Set<E> elementSet;
 
     Set<E> createElementSet() {
       return Collections.<E>unmodifiableSet(.elementSet());
     }
 
     @Override
     public Set<E> elementSet() {
       Set<E> es = ;
       return (es == null) ?  = createElementSet() : es;
     }
 
     transient Set<Multiset.Entry<E>> entrySet;
 
     @SuppressWarnings("unchecked")
     @Override public Set<Multiset.Entry<E>> entrySet() {
       Set<Multiset.Entry<E>> es = ;
       return (es == null)
           // Safe because the returned set is made unmodifiable and Entry
           // itself is readonly
           ?  = (Set) Collections.unmodifiableSet(.entrySet())
           : es;
     }
 
     @SuppressWarnings("unchecked")
     @Override public Iterator<E> iterator() {
       // Safe because the returned Iterator is made unmodifiable
       return (Iterator<E>) Iterators.unmodifiableIterator(.iterator());
     }
 
     @Override public boolean add(E element) {
       throw new UnsupportedOperationException();
     }
 
     @Override public int add(E elementint occurences) {
       throw new UnsupportedOperationException();
     }
 
     @Override public boolean addAll(Collection<? extends E> elementsToAdd) {
       throw new UnsupportedOperationException();
     }
 
     @Override public boolean remove(Object element) {
       throw new UnsupportedOperationException();
     }
 
     @Override public int remove(Object elementint occurrences) {
       throw new UnsupportedOperationException();
     }
 
     @Override public boolean removeAll(Collection<?> elementsToRemove) {
       throw new UnsupportedOperationException();
     }
 
     @Override public boolean retainAll(Collection<?> elementsToRetain) {
       throw new UnsupportedOperationException();
     }
 
     @Override public void clear() {
       throw new UnsupportedOperationException();
     }
 
     @Override public int setCount(E elementint count) {
       throw new UnsupportedOperationException();
     }
 
     @Override public boolean setCount(E elementint oldCountint newCount) {
       throw new UnsupportedOperationException();
     }
 
     private static final long serialVersionUID = 0;
   }

  
Returns an unmodifiable view of the specified sorted multiset. Query operations on the returned multiset "read through" to the specified multiset, and attempts to modify the returned multiset result in an java.lang.UnsupportedOperationException.

The returned multiset will be serializable if the specified multiset is serializable.

Parameters:
sortedMultiset the sorted multiset for which an unmodifiable view is to be generated
Returns:
an unmodifiable view of the multiset
Since:
11.0
 
   @Beta
   public static <E> SortedMultiset<E> unmodifiableSortedMultiset(
       SortedMultiset<E> sortedMultiset) {
     // it's in its own file so it can be emulated for GWT
     return new UnmodifiableSortedMultiset<E>(checkNotNull(sortedMultiset));
   }

  
Returns an immutable multiset entry with the specified element and count. The entry will be serializable if e is.

Parameters:
e the element to be associated with the returned entry
n the count to be associated with the returned entry
Throws:
java.lang.IllegalArgumentException if n is negative
 
   public static <E> Multiset.Entry<E> immutableEntry(@Nullable E eint n) {
     return new ImmutableEntry<E>(en);
   }
 
   static final class ImmutableEntry<E> extends AbstractEntry<E> implements
       Serializable {
     @Nullable final E element;
     final int count;
 
     ImmutableEntry(@Nullable E elementint count) {
       this. = element;
       this. = count;
       checkNonnegative(count"count");
     }
 
     @Override
     @Nullable public E getElement() {
       return ;
     }
 
     @Override
     public int getCount() {
       return ;
     }
 
     private static final long serialVersionUID = 0;
   }

  
Returns a view of the elements of unfiltered that satisfy a predicate. The returned multiset is a live view of unfiltered; changes to one affect the other.

The resulting multiset's iterators, and those of its entrySet() and elementSet(), do not support remove(). However, all other multiset methods supported by unfiltered are supported by the returned multiset. When given an element that doesn't satisfy the predicate, the multiset's add() and addAll() methods throw an java.lang.IllegalArgumentException. When methods such as removeAll() and clear() are called on the filtered multiset, only elements that satisfy the filter will be removed from the underlying multiset.

The returned multiset isn't threadsafe or serializable, even if unfiltered is.

Many of the filtered multiset's methods, such as size(), iterate across every element in the underlying multiset and determine which elements satisfy the filter. When a live view is not needed, it may be faster to copy the returned multiset and use the copy.

Warning: predicate must be consistent with equals, as documented at com.google.common.base.Predicate.apply(java.lang.Object). Do not provide a predicate such as Predicates.instanceOf(ArrayList.class), which is inconsistent with equals. (See Iterables.filter(java.lang.Iterable,java.lang.Class) for related functionality.)

Since:
14.0
 
   @Beta
   public static <E> Multiset<E> filter(Multiset<E> unfilteredPredicate<? super E> predicate) {
     if (unfiltered instanceof FilteredMultiset) {
       // Support clear(), removeAll(), and retainAll() when filtering a filtered
       // collection.
       FilteredMultiset<E> filtered = (FilteredMultiset<E>) unfiltered;
       Predicate<E> combinedPredicate
           = Predicates.<E>and(filtered.predicatepredicate);
       return new FilteredMultiset<E>(filtered.unfilteredcombinedPredicate);
     }
     return new FilteredMultiset<E>(unfilteredpredicate);
   }
 
   private static final class FilteredMultiset<E> extends AbstractMultiset<E> {
     final Multiset<E> unfiltered;
     final Predicate<? super E> predicate;
 
     FilteredMultiset(Multiset<E> unfilteredPredicate<? super E> predicate) {
       this. = checkNotNull(unfiltered);
       this. = checkNotNull(predicate);
     }
 
     @Override
     public UnmodifiableIterator<E> iterator() {
       return Iterators.filter(.iterator(), );
     }
 
     @Override
     Set<E> createElementSet() {
       return Sets.filter(.elementSet(), );
     }
 
     @Override
     Set<Entry<E>> createEntrySet() {
       return Sets.filter(.entrySet(), new Predicate<Entry<E>>() {
         @Override
         public boolean apply(Entry<E> entry) {
           return .apply(entry.getElement());
         }
       });
     }
 
     @Override
     Iterator<Entry<E>> entryIterator() {
       throw new AssertionError("should never be called");
     }
 
     @Override
     int distinctElements() {
       return elementSet().size();
     }
 
     @Override
     public int count(@Nullable Object element) {
       int count = .count(element);
       if (count > 0) {
         @SuppressWarnings("unchecked"// element is equal to an E
         E e = (E) element;
         return .apply(e) ? count : 0;
       }
       return 0;
     }
 
     @Override
     public int add(@Nullable E elementint occurrences) {
       checkArgument(.apply(element),
           "Element %s does not match predicate %s"element);
       return .add(elementoccurrences);
     }
 
     @Override
     public int remove(@Nullable Object elementint occurrences) {
       checkNonnegative(occurrences"occurrences");
       if (occurrences == 0) {
         return count(element);
       } else {
         return contains(element) ? .remove(elementoccurrences) : 0;
       }
     }
 
     @Override
     public void clear() {
       elementSet().clear();
     }
   }

  
Returns the expected number of distinct elements given the specified elements. The number of distinct elements is only computed if elements is an instance of Multiset; otherwise the default value of 11 is returned.
 
   static int inferDistinctElements(Iterable<?> elements) {
     if (elements instanceof Multiset) {
       return ((Multiset<?>) elements).elementSet().size();
     }
     return 11; // initial capacity will be rounded up to 16
   }

  
Returns an unmodifiable view of the union of two multisets. In the returned multiset, the count of each element is the maximum of its counts in the two backing multisets. The iteration order of the returned multiset matches that of the element set of multiset1 followed by the members of the element set of multiset2 that are not contained in multiset1, with repeated occurrences of the same element appearing consecutively.

Results are undefined if multiset1 and multiset2 are based on different equivalence relations (as HashMultiset and TreeMultiset are).

Since:
14.0
 
   @Beta
   public static <E> Multiset<E> union(
       final Multiset<? extends E> multiset1final Multiset<? extends E> multiset2) {
     checkNotNull(multiset1);
     checkNotNull(multiset2);
 
     return new AbstractMultiset<E>() {
       @Override
       public boolean contains(@Nullable Object element) {
         return multiset1.contains(element) || multiset2.contains(element);
       }
 
       @Override
       public boolean isEmpty() {
         return multiset1.isEmpty() && multiset2.isEmpty();
       }
 
       @Override
       public int count(Object element) {
         return Math.max(multiset1.count(element), multiset2.count(element));
       }
 
       @Override
       Set<E> createElementSet() {
         return Sets.union(multiset1.elementSet(), multiset2.elementSet());
       }
 
       @Override
       Iterator<Entry<E>> entryIterator() {
         final Iterator<? extends Entry<? extends E>> iterator1
             = multiset1.entrySet().iterator();
         final Iterator<? extends Entry<? extends E>> iterator2
             = multiset2.entrySet().iterator();
         // TODO(user): consider making the entries live views
         return new AbstractIterator<Entry<E>>() {
           @Override
           protected Entry<E> computeNext() {
             if (iterator1.hasNext()) {
               Entry<? extends E> entry1 = iterator1.next();
               E element = entry1.getElement();
               int count = Math.max(entry1.getCount(), multiset2.count(element));
               return immutableEntry(elementcount);
             }
             while (iterator2.hasNext()) {
               Entry<? extends E> entry2 = iterator2.next();
               E element = entry2.getElement();
               if (!multiset1.contains(element)) {
                 return immutableEntry(elemententry2.getCount());
               }
             }
             return endOfData();
           }
         };
       }
 
       @Override
       int distinctElements() {
         return elementSet().size();
       }
     };
   }

  
Returns an unmodifiable view of the intersection of two multisets. In the returned multiset, the count of each element is the minimum of its counts in the two backing multisets, with elements that would have a count of 0 not included. The iteration order of the returned multiset matches that of the element set of multiset1, with repeated occurrences of the same element appearing consecutively.

Results are undefined if multiset1 and multiset2 are based on different equivalence relations (as HashMultiset and TreeMultiset are).

Since:
2.0
 
   public static <E> Multiset<E> intersection(
       final Multiset<E> multiset1final Multiset<?> multiset2) {
     checkNotNull(multiset1);
     checkNotNull(multiset2);
 
     return new AbstractMultiset<E>() {
       @Override
       public int count(Object element) {
         int count1 = multiset1.count(element);
         return (count1 == 0) ? 0 : Math.min(count1multiset2.count(element));
       }
 
       @Override
       Set<E> createElementSet() {
         return Sets.intersection(
             multiset1.elementSet(), multiset2.elementSet());
       }
 
       @Override
       Iterator<Entry<E>> entryIterator() {
         final Iterator<Entry<E>> iterator1 = multiset1.entrySet().iterator();
         // TODO(user): consider making the entries live views
         return new AbstractIterator<Entry<E>>() {
           @Override
           protected Entry<E> computeNext() {
             while (iterator1.hasNext()) {
               Entry<E> entry1 = iterator1.next();
               E element = entry1.getElement();
               int count = Math.min(entry1.getCount(), multiset2.count(element));
               if (count > 0) {
                 return immutableEntry(elementcount);
               }
             }
             return endOfData();
           }
         };
       }
 
       @Override
       int distinctElements() {
         return elementSet().size();
       }
     };
   }

  
Returns an unmodifiable view of the sum of two multisets. In the returned multiset, the count of each element is the sum of its counts in the two backing multisets. The iteration order of the returned multiset matches that of the element set of multiset1 followed by the members of the element set of multiset2 that are not contained in multiset1, with repeated occurrences of the same element appearing consecutively.

Results are undefined if multiset1 and multiset2 are based on different equivalence relations (as HashMultiset and TreeMultiset are).

Since:
14.0
 
   @Beta
   public static <E> Multiset<E> sum(
       final Multiset<? extends E> multiset1final Multiset<? extends E> multiset2) {
     checkNotNull(multiset1);
     checkNotNull(multiset2);
 
     // TODO(user): consider making the entries live views
     return new AbstractMultiset<E>() {
       @Override
       public boolean contains(@Nullable Object element) {
         return multiset1.contains(element) || multiset2.contains(element);
       }
 
       @Override
       public boolean isEmpty() {
         return multiset1.isEmpty() && multiset2.isEmpty();
       }
 
       @Override
       public int size() {
         return multiset1.size() + multiset2.size();
       }
 
       @Override
       public int count(Object element) {
         return multiset1.count(element) + multiset2.count(element);
       }
 
       @Override
       Set<E> createElementSet() {
         return Sets.union(multiset1.elementSet(), multiset2.elementSet());
       }
 
       @Override
       Iterator<Entry<E>> entryIterator() {
         final Iterator<? extends Entry<? extends E>> iterator1
             = multiset1.entrySet().iterator();
         final Iterator<? extends Entry<? extends E>> iterator2
             = multiset2.entrySet().iterator();
         return new AbstractIterator<Entry<E>>() {
           @Override
           protected Entry<E> computeNext() {
             if (iterator1.hasNext()) {
               Entry<? extends E> entry1 = iterator1.next();
               E element = entry1.getElement();
               int count = entry1.getCount() + multiset2.count(element);
               return immutableEntry(elementcount);
             }
             while (iterator2.hasNext()) {
               Entry<? extends E> entry2 = iterator2.next();
               E element = entry2.getElement();
               if (!multiset1.contains(element)) {
                 return immutableEntry(elemententry2.getCount());
               }
             }
             return endOfData();
           }
         };
       }
 
       @Override
       int distinctElements() {
         return elementSet().size();
       }
     };
   }

  
Returns an unmodifiable view of the difference of two multisets. In the returned multiset, the count of each element is the result of the zero-truncated subtraction of its count in the second multiset from its count in the first multiset, with elements that would have a count of 0 not included. The iteration order of the returned multiset matches that of the element set of multiset1, with repeated occurrences of the same element appearing consecutively.

Results are undefined if multiset1 and multiset2 are based on different equivalence relations (as HashMultiset and TreeMultiset are).

Since:
14.0
 
   @Beta
   public static <E> Multiset<E> difference(
       final Multiset<E> multiset1final Multiset<?> multiset2) {
     checkNotNull(multiset1);
     checkNotNull(multiset2);
 
     // TODO(user): consider making the entries live views
     return new AbstractMultiset<E>() {
       @Override
       public int count(@Nullable Object element) {
         int count1 = multiset1.count(element);
         return (count1 == 0) ? 0 :
             Math.max(0, count1 - multiset2.count(element));
       }
 
       @Override
       Iterator<Entry<E>> entryIterator() {
         final Iterator<Entry<E>> iterator1 = multiset1.entrySet().iterator();
         return new AbstractIterator<Entry<E>>() {
           @Override
           protected Entry<E> computeNext() {
             while (iterator1.hasNext()) {
               Entry<E> entry1 = iterator1.next();
               E element = entry1.getElement();
               int count = entry1.getCount() - multiset2.count(element);
               if (count > 0) {
                 return immutableEntry(elementcount);
               }
             }
             return endOfData();
           }
         };
       }
 
       @Override
       int distinctElements() {
         return Iterators.size(entryIterator());
       }
     };
   }

  
Returns true if subMultiset.count(o) <= superMultiset.count(o) for all o.

Since:
10.0
 
   public static boolean containsOccurrences(
       Multiset<?> superMultisetMultiset<?> subMultiset) {
     checkNotNull(superMultiset);
     checkNotNull(subMultiset);
     for (Entry<?> entry : subMultiset.entrySet()) {
       int superCount = superMultiset.count(entry.getElement());
       if (superCount < entry.getCount()) {
         return false;
       }
     }
     return true;
   }

  
Modifies multisetToModify so that its count for an element e is at most multisetToRetain.count(e).

To be precise, multisetToModify.count(e) is set to Math.min(multisetToModify.count(e), multisetToRetain.count(e)). This is similar to intersection (multisetToModify, multisetToRetain), but mutates multisetToModify instead of returning a view.

In contrast, multisetToModify.retainAll(multisetToRetain) keeps all occurrences of elements that appear at all in multisetToRetain, and deletes all occurrences of all other elements.

Returns:
true if multisetToModify was changed as a result of this operation
Since:
10.0
 
   public static boolean retainOccurrences(Multiset<?> multisetToModify,
       Multiset<?> multisetToRetain) {
     return retainOccurrencesImpl(multisetToModifymultisetToRetain);
   }

  
Delegate implementation which cares about the element type.
 
   private static <E> boolean retainOccurrencesImpl(
       Multiset<E> multisetToModifyMultiset<?> occurrencesToRetain) {
     checkNotNull(multisetToModify);
     checkNotNull(occurrencesToRetain);
     // Avoiding ConcurrentModificationExceptions is tricky.
     Iterator<Entry<E>> entryIterator = multisetToModify.entrySet().iterator();
     boolean changed = false;
     while (entryIterator.hasNext()) {
       Entry<E> entry = entryIterator.next();
       int retainCount = occurrencesToRetain.count(entry.getElement());
       if (retainCount == 0) {
         entryIterator.remove();
         changed = true;
       } else if (retainCount < entry.getCount()) {
         multisetToModify.setCount(entry.getElement(), retainCount);
         changed = true;
       }
     }
     return changed;
   }

  
For each occurrence of an element e in occurrencesToRemove, removes one occurrence of e in multisetToModify.

Equivalently, this method modifies multisetToModify so that multisetToModify.count(e) is set to Math.max(0, multisetToModify.count(e) - occurrencesToRemove.count(e)).

This is not the same as multisetToModify. removeAll(occurrencesToRemove), which removes all occurrences of elements that appear in occurrencesToRemove. However, this operation is equivalent to, albeit sometimes more efficient than, the following:

   for (E e : occurrencesToRemove) {
     multisetToModify.remove(e);
   }

Returns:
true if multisetToModify was changed as a result of this operation
Since:
18.0 (present in 10.0 with a requirement that the second parameter be a Multiset)
 
   public static boolean removeOccurrences(
       Multiset<?> multisetToModifyIterable<?> occurrencesToRemove) {
     if (occurrencesToRemove instanceof Multiset) {
       return removeOccurrencesImpl(
           multisetToModify, (Multiset<?>) occurrencesToRemove);
     } else {
       return removeOccurrencesImpl(multisetToModifyoccurrencesToRemove);
     }
   }
 
   private static boolean removeOccurrencesImpl(
       Multiset<?> multisetToModifyIterable<?> occurrencesToRemove) {
     checkNotNull(multisetToModify);
     checkNotNull(occurrencesToRemove);
     boolean changed = false;
     for (Object o : occurrencesToRemove) {
       changed |= multisetToModify.remove(o);
     }
     return changed;
   }

  
Delegate that cares about the element types in multisetToModify.
 
   private static <E> boolean removeOccurrencesImpl(
       Multiset<E> multisetToModifyMultiset<?> occurrencesToRemove) {
     // TODO(user): generalize to removing an Iterable, perhaps
     checkNotNull(multisetToModify);
     checkNotNull(occurrencesToRemove);
 
     boolean changed = false;
     Iterator<Entry<E>> entryIterator = multisetToModify.entrySet().iterator();
     while (entryIterator.hasNext()) {
       Entry<E> entry = entryIterator.next();
       int removeCount = occurrencesToRemove.count(entry.getElement());
       if (removeCount >= entry.getCount()) {
         entryIterator.remove();
         changed = true;
       } else if (removeCount > 0) {
         multisetToModify.remove(entry.getElement(), removeCount);
         changed = true;
       }
     }
     return changed;
   }

  
Implementation of the equals, hashCode, and toString methods of Multiset.Entry.
 
   abstract static class AbstractEntry<E> implements Multiset.Entry<E> {
    
Indicates whether an object equals this entry, following the behavior specified in Multiset.Entry.equals(java.lang.Object).
 
     @Override public boolean equals(@Nullable Object object) {
       if (object instanceof Multiset.Entry) {
         Multiset.Entry<?> that = (Multiset.Entry<?>) object;
         return this.getCount() == that.getCount()
             && Objects.equal(this.getElement(), that.getElement());
       }
       return false;
     }

    
Return this entry's hash code, following the behavior specified in Multiset.Entry.hashCode().
 
     @Override public int hashCode() {
       E e = getElement();
       return ((e == null) ? 0 : e.hashCode()) ^ getCount();
     }

    
Returns a string representation of this multiset entry. The string representation consists of the associated element if the associated count is one, and otherwise the associated element followed by the characters " x " (space, x and space) followed by the count. Elements and counts are converted to strings as by String.valueOf.
 
     @Override public String toString() {
       String text = String.valueOf(getElement());
       int n = getCount();
       return (n == 1) ? text : (text + " x " + n);
     }
   }

  
An implementation of Multiset.equals(java.lang.Object).
 
   static boolean equalsImpl(Multiset<?> multiset, @Nullable Object object) {
     if (object == multiset) {
       return true;
     }
     if (object instanceof Multiset) {
       Multiset<?> that = (Multiset<?>) object;
       /*
        * We can't simply check whether the entry sets are equal, since that
        * approach fails when a TreeMultiset has a comparator that returns 0
        * when passed unequal elements.
        */
 
       if (multiset.size() != that.size()
           || multiset.entrySet().size() != that.entrySet().size()) {
         return false;
       }
       for (Entry<?> entry : that.entrySet()) {
         if (multiset.count(entry.getElement()) != entry.getCount()) {
           return false;
         }
       }
       return true;
     }
     return false;
   }

  
 
   static <E> boolean addAllImpl(
       Multiset<E> selfCollection<? extends E> elements) {
     if (elements.isEmpty()) {
       return false;
     }
     if (elements instanceof Multiset) {
       Multiset<? extends E> that = cast(elements);
       for (Entry<? extends E> entry : that.entrySet()) {
         self.add(entry.getElement(), entry.getCount());
       }
     } else {
       Iterators.addAll(selfelements.iterator());
     }
     return true;
   }

  
 
   static boolean removeAllImpl(
       Multiset<?> selfCollection<?> elementsToRemove) {
     Collection<?> collection = (elementsToRemove instanceof Multiset)
         ? ((Multiset<?>) elementsToRemove).elementSet() : elementsToRemove;
 
     return self.elementSet().removeAll(collection);
   }

  
 
   static boolean retainAllImpl(
       Multiset<?> selfCollection<?> elementsToRetain) {
     checkNotNull(elementsToRetain);
     Collection<?> collection = (elementsToRetain instanceof Multiset)
         ? ((Multiset<?>) elementsToRetain).elementSet() : elementsToRetain;
 
     return self.elementSet().retainAll(collection);
   }

  
 
   static <E> int setCountImpl(Multiset<E> self, E elementint count) {
     checkNonnegative(count"count");
 
     int oldCount = self.count(element);
 
     int delta = count - oldCount;
     if (delta > 0) {
       self.add(elementdelta);
     } else if (delta < 0) {
       self.remove(element, -delta);
     }
 
     return oldCount;
   }

  
 
   static <E> boolean setCountImpl(
       Multiset<E> self, E elementint oldCountint newCount) {
     checkNonnegative(oldCount"oldCount");
     checkNonnegative(newCount"newCount");
 
     if (self.count(element) == oldCount) {
       self.setCount(elementnewCount);
       return true;
     } else {
       return false;
     }
   }
 
   abstract static class ElementSet<E> extends Sets.ImprovedAbstractSet<E> {
     abstract Multiset<E> multiset();
 
     @Override public void clear() {
       multiset().clear();
     }
 
     @Override public boolean contains(Object o) {
       return multiset().contains(o);
     }
 
     @Override public boolean containsAll(Collection<?> c) {
       return multiset().containsAll(c);
     }
 
     @Override public boolean isEmpty() {
       return multiset().isEmpty();
     }
 
     @Override public Iterator<E> iterator() {
       return new TransformedIterator<Entry<E>, E>(multiset().entrySet().iterator()) {
         @Override
         E transform(Entry<E> entry) {
           return entry.getElement();
         }
       };
     }
 
     @Override
     public boolean remove(Object o) {
       int count = multiset().count(o);
       if (count > 0) {
         multiset().remove(ocount);
         return true;
       }
       return false;
     }
 
     @Override public int size() {
       return multiset().entrySet().size();
     }
   }
 
   abstract static class EntrySet<E> extends Sets.ImprovedAbstractSet<Entry<E>> {
     abstract Multiset<E> multiset();
 
     @Override public boolean contains(@Nullable Object o) {
       if (o instanceof Entry) {
         /*
          * The GWT compiler wrongly issues a warning here.
          */
         @SuppressWarnings("cast")
         Entry<?> entry = (Entry<?>) o;
         if (entry.getCount() <= 0) {
           return false;
         }
         int count = multiset().count(entry.getElement());
         return count == entry.getCount();
 
       }
       return false;
     }
 
     // GWT compiler warning; see contains().
     @SuppressWarnings("cast")
     @Override public boolean remove(Object object) {
       if (object instanceof Multiset.Entry) {
         Entry<?> entry = (Entry<?>) object;
         Object element = entry.getElement();
         int entryCount = entry.getCount();
         if (entryCount != 0) {
           // Safe as long as we never add a new entry, which we won't.
           @SuppressWarnings("unchecked")
           Multiset<Objectmultiset = (Multisetmultiset();
           return multiset.setCount(elemententryCount, 0);
         }
       }
       return false;
     }
    @Override public void clear() {
      multiset().clear();
    }
  }

  
An implementation of Multiset.iterator().
  static <E> Iterator<E> iteratorImpl(Multiset<E> multiset) {
    return new MultisetIteratorImpl<E>(
        multisetmultiset.entrySet().iterator());
  }
  static final class MultisetIteratorImpl<E> implements Iterator<E> {
    private final Multiset<E> multiset;
    private final Iterator<Entry<E>> entryIterator;
    private Entry<E> currentEntry;
    
Count of subsequent elements equal to current element
    private int laterCount;
    
Count of all elements equal to current element
    private int totalCount;
    private boolean canRemove;
        Multiset<E> multisetIterator<Entry<E>> entryIterator) {
      this. = multiset;
      this. = entryIterator;
    }
    @Override
    public boolean hasNext() {
      return  > 0 || .hasNext();
    }
    @Override
    public E next() {
      if (!hasNext()) {
        throw new NoSuchElementException();
      }
      if ( == 0) {
         = .next();
         =  = .getCount();
      }
      --;
       = true;
      return .getElement();
    }
    @Override
    public void remove() {
      if ( == 1) {
        .remove();
      } else {
      }
      --;
       = false;
    }
  }

  
An implementation of java.util.Collection.size().
  static int sizeImpl(Multiset<?> multiset) {
    long size = 0;
    for (Entry<?> entry : multiset.entrySet()) {
      size += entry.getCount();
    }
    return Ints.saturatedCast(size);
  }

  
Used to avoid http://bugs.sun.com/view_bug.do?bug_id=6558557
  static <T> Multiset<T> cast(Iterable<T> iterable) {
    return (Multiset<T>) iterable;
  }
  private static final Ordering<Entry<?>> DECREASING_COUNT_ORDERING = new Ordering<Entry<?>>() {
    @Override
    public int compare(Entry<?> entry1Entry<?> entry2) {
      return Ints.compare(entry2.getCount(), entry1.getCount());
    }
  };

  
Returns a copy of multiset as an ImmutableMultiset whose iteration order is highest count first, with ties broken by the iteration order of the original multiset.

Since:
11.0
  public static <E> ImmutableMultiset<E> copyHighestCountFirst(Multiset<E> multiset) {
    List<Entry<E>> sortedEntries =
    return ImmutableMultiset.copyFromEntries(sortedEntries);
  }