/* * Copyright (C) 2012 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 java.util.Comparator; import java.util.Iterator; import java.util.NavigableSet; import java.util.Set; import com.google.common.annotations.GwtCompatible; /** * A skeleton implementation of a descending multiset. Only needs * {@code forwardMultiset()} and {@code entryIterator()}. * * @author Louis Wasserman */ @GwtCompatible(emulated = true) abstract class DescendingMultiset extends ForwardingMultiset implements SortedMultiset { abstract SortedMultiset forwardMultiset(); private transient Comparator comparator; @Override public Comparator comparator() { Comparator result = comparator; if (result == null) { return comparator = Ordering.from(forwardMultiset().comparator()).reverse(); } return result; } private transient NavigableSet elementSet; @Override public NavigableSet elementSet() { NavigableSet result = elementSet; if (result == null) { return elementSet = new SortedMultisets.NavigableElementSet(this); } return result; } @Override public Entry pollFirstEntry() { return forwardMultiset().pollLastEntry(); } @Override public Entry pollLastEntry() { return forwardMultiset().pollFirstEntry(); } @Override public SortedMultiset headMultiset(E toElement, BoundType boundType) { return forwardMultiset().tailMultiset(toElement, boundType).descendingMultiset(); } @Override public SortedMultiset subMultiset(E fromElement, BoundType fromBoundType, E toElement, BoundType toBoundType) { return forwardMultiset().subMultiset(toElement, toBoundType, fromElement, fromBoundType).descendingMultiset(); } @Override public SortedMultiset tailMultiset(E fromElement, BoundType boundType) { return forwardMultiset().headMultiset(fromElement, boundType).descendingMultiset(); } @Override protected Multiset delegate() { return forwardMultiset(); } @Override public SortedMultiset descendingMultiset() { return forwardMultiset(); } @Override public Entry firstEntry() { return forwardMultiset().lastEntry(); } @Override public Entry lastEntry() { return forwardMultiset().firstEntry(); } abstract Iterator> entryIterator(); private transient Set> entrySet; @Override public Set> entrySet() { Set> result = entrySet; return (result == null) ? entrySet = createEntrySet() : result; } Set> createEntrySet() { return new Multisets.EntrySet() { @Override Multiset multiset() { return DescendingMultiset.this; } @Override public Iterator> iterator() { return entryIterator(); } @Override public int size() { return forwardMultiset().entrySet().size(); } }; } @Override public Iterator iterator() { return Multisets.iteratorImpl(this); } @Override public Object[] toArray() { return standardToArray(); } @Override public T[] toArray(T[] array) { return standardToArray(array); } @Override public String toString() { return entrySet().toString(); } }