11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2011 The Guava Authors
31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License"); you may not
51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * use this file except in compliance with the License. You may obtain a copy of
61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the License at
71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0
91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software
111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * License for the specific language governing permissions and limitations under
141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the License.
151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.collect;
181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtCompatible;
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.Multiset.Entry;
211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Comparator;
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Iterator;
241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.NoSuchElementException;
251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Set;
261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.SortedSet;
271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/**
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Provides static utility methods for creating and working with
301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link SortedMultiset} instances.
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Louis Wasserman
331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible
351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertfinal class SortedMultisets {
361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private SortedMultisets() {
371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * A skeleton implementation for {@link SortedMultiset#elementSet}.
411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static abstract class ElementSet<E> extends Multisets.ElementSet<E> implements
431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      SortedSet<E> {
441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override abstract SortedMultiset<E> multiset();
451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Comparator<? super E> comparator() {
471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return multiset().comparator();
481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public SortedSet<E> subSet(E fromElement, E toElement) {
511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return multiset().subMultiset(fromElement, BoundType.CLOSED, toElement,
521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          BoundType.OPEN).elementSet();
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public SortedSet<E> headSet(E toElement) {
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return multiset().headMultiset(toElement, BoundType.OPEN).elementSet();
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public SortedSet<E> tailSet(E fromElement) {
601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return multiset().tailMultiset(fromElement, BoundType.CLOSED)
611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          .elementSet();
621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public E first() {
651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return getElementOrThrow(multiset().firstEntry());
661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public E last() {
691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return getElementOrThrow(multiset().lastEntry());
701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static <E> E getElementOrThrow(Entry<E> entry) {
741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (entry == null) {
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new NoSuchElementException();
761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return entry.getElement();
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * A skeleton implementation of a descending multiset.  Only needs
821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code forwardMultiset()} and {@code entryIterator()}.
831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static abstract class DescendingMultiset<E> extends ForwardingMultiset<E>
851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      implements SortedMultiset<E> {
861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    abstract SortedMultiset<E> forwardMultiset();
871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private transient Comparator<? super E> comparator;
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Comparator<? super E> comparator() {
911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Comparator<? super E> result = comparator;
921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (result == null) {
931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return comparator =
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            Ordering.from(forwardMultiset().comparator()).<E>reverse();
951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return result;
971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private transient SortedSet<E> elementSet;
1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public SortedSet<E> elementSet() {
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      SortedSet<E> result = elementSet;
1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (result == null) {
1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return elementSet = new SortedMultisets.ElementSet<E>() {
1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          @Override SortedMultiset<E> multiset() {
1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return DescendingMultiset.this;
1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        };
1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return result;
1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Entry<E> pollFirstEntry() {
1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return forwardMultiset().pollLastEntry();
1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Entry<E> pollLastEntry() {
1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return forwardMultiset().pollFirstEntry();
1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public SortedMultiset<E> headMultiset(E toElement,
1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        BoundType boundType) {
1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return forwardMultiset().tailMultiset(toElement, boundType)
1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          .descendingMultiset();
1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public SortedMultiset<E> subMultiset(E fromElement,
1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        BoundType fromBoundType, E toElement, BoundType toBoundType) {
1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return forwardMultiset().subMultiset(toElement, toBoundType, fromElement,
1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          fromBoundType).descendingMultiset();
1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public SortedMultiset<E> tailMultiset(E fromElement,
1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        BoundType boundType) {
1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return forwardMultiset().headMultiset(fromElement, boundType)
1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          .descendingMultiset();
1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override protected Multiset<E> delegate() {
1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return forwardMultiset();
1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public SortedMultiset<E> descendingMultiset() {
1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return forwardMultiset();
1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Entry<E> firstEntry() {
1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return forwardMultiset().lastEntry();
1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Entry<E> lastEntry() {
1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return forwardMultiset().firstEntry();
1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    abstract Iterator<Entry<E>> entryIterator();
1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private transient Set<Entry<E>> entrySet;
1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Set<Entry<E>> entrySet() {
1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Set<Entry<E>> result = entrySet;
1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return (result == null) ? entrySet = createEntrySet() : result;
1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Set<Entry<E>> createEntrySet() {
1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return new Multisets.EntrySet<E>() {
1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override Multiset<E> multiset() {
1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return DescendingMultiset.this;
1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public Iterator<Entry<E>> iterator() {
1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return entryIterator();
1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public int size() {
1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return forwardMultiset().entrySet().size();
1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      };
1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Iterator<E> iterator() {
1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Multisets.iteratorImpl(this);
1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Object[] toArray() {
1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return standardToArray();
1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public <T> T[] toArray(T[] array) {
1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return standardToArray(array);
1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public String toString() {
1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return entrySet().toString();
1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
197