guava/src/com/google/common/collect/Multisets.java
@Beta
  public static <E> Multiset<E> difference(
      final Multiset<E> multiset1, final Multiset<?> multiset2) {
    checkNotNull(multiset1);
    checkNotNull(multiset2);

    // TODO(lowasser): consider making the entries live views
    return new ViewMultiset<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
      public void clear() {
        throw new UnsupportedOperationException();
      }

      @Override
      Iterator<E> elementIterator() {
        final Iterator<Entry<E>> iterator1 = multiset1.entrySet().iterator();
        return new AbstractIterator<E>() {
          @Override
          protected E computeNext() {
            while (iterator1.hasNext()) {
              Entry<E> entry1 = iterator1.next();
              E element = entry1.getElement();
              if (entry1.getCount() > multiset2.count(element)) {
                return element;
              }
            }
            return endOfData();
          }
        };
      }

      @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(element, count);
              }
            }
            return endOfData();
          }
        };
      }

      @Override
      int distinctElements() {
        return Iterators.size(entryIterator());
      }
    };
  }
@Beta
  public static <E> Multiset<E> difference(
      final Multiset<E> multiset1, final Multiset<?> multiset2) {
    checkNotNull(multiset1);
    checkNotNull(multiset2);

    // TODO(lowasser): consider making the entries live views
    return new ViewMultiset<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
      public void clear() {
        throw new UnsupportedOperationException();
      }

      @Override
      Iterator<E> elementIterator() {
        final Iterator<Entry<E>> iterator1 = multiset1.entrySet().iterator();
        return new AbstractIterator<E>() {
          @Override
          protected E computeNext() {
            while (iterator1.hasNext()) {
              Entry<E> entry1 = iterator1.next();
              E element = entry1.getElement();
              if (entry1.getCount() > multiset2.count(element)) {
                return element;
              }
            }
            return endOfData();
          }
        };
      }

      @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(element, count);
              }
            }
            return endOfData();
          }
        };
      }

      @Override
      int distinctElements() {
        return Iterators.size(entryIterator());
      }
    };
  }
@ Beta public static < E > Multiset < E > difference ( final Multiset < E > multiset1 , final Multiset < ? > multiset2 ) { checkNotNull ( multiset1 ) ; checkNotNull ( multiset2 ) ; // TODO(lowasser): consider making the entries live views return new ViewMultiset < 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 public void clear ( ) { throw new UnsupportedOperationException ( ) ; } @ Override Iterator < E > elementIterator ( ) { final Iterator < Entry < E > > iterator1 = multiset1 . entrySet ( ) . iterator ( ) ; return new AbstractIterator < E > ( ) { @ Override protected E computeNext ( ) { while ( iterator1 . hasNext ( ) ) { Entry < E > entry1 = iterator1 . next ( ) ; E element = entry1 . getElement ( ) ; if ( entry1 . getCount ( ) > multiset2 . count ( element ) ) { return element ; } } return endOfData ( ) ; } } ; } @ 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 ( element , count ) ; } } return endOfData ( ) ; } } ; } @ Override int distinctElements ( ) { return Iterators . size ( entryIterator ( ) ) ; } } ; }
Returns an unmodifiable view of the difference of two multisets. In the returned multiset, the
count of each element is the result of the <i>zero-truncated subtraction</i> 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 {@code multiset1}, with repeated occurrences of the same element appearing consecutively.

<p>Results are undefined if {@code multiset1} and {@code multiset2} are based on different
equivalence relations (as {@code HashMultiset} and {@code TreeMultiset} are).

@since 14.0
Returns an unmodifiable view of the difference of two multisets . In the returned multiset the count of each element is the result of the <i > zero - truncated subtraction< / i > 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 { @code multiset1 } with repeated occurrences of the same element appearing consecutively .