View Javadoc
1   /*
2    * Copyright (C) 2011 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5    * use this file except in compliance with the License. You may obtain a copy of
6    * 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, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations under
14   * the License.
15   */
16  
17  package com.google.common.collect;
18  
19  import static com.google.common.collect.BoundType.CLOSED;
20  import static com.google.common.collect.BoundType.OPEN;
21  
22  import com.google.common.annotations.GwtCompatible;
23  import com.google.common.annotations.GwtIncompatible;
24  import com.google.common.collect.Multiset.Entry;
25  import com.google.j2objc.annotations.Weak;
26  import java.util.Comparator;
27  import java.util.Iterator;
28  import java.util.NavigableSet;
29  import java.util.NoSuchElementException;
30  import java.util.SortedSet;
31  import javax.annotation.Nullable;
32  
33  /**
34   * Provides static utility methods for creating and working with
35   * {@link SortedMultiset} instances.
36   *
37   * @author Louis Wasserman
38   */
39  @GwtCompatible(emulated = true)
40  final class SortedMultisets {
41    private SortedMultisets() {}
42  
43    /**
44     * A skeleton implementation for {@link SortedMultiset#elementSet}.
45     */
46    static class ElementSet<E> extends Multisets.ElementSet<E> implements SortedSet<E> {
47      @Weak private final SortedMultiset<E> multiset;
48  
49      ElementSet(SortedMultiset<E> multiset) {
50        this.multiset = multiset;
51      }
52  
53      @Override
54      final SortedMultiset<E> multiset() {
55        return multiset;
56      }
57  
58      @Override
59      public Comparator<? super E> comparator() {
60        return multiset().comparator();
61      }
62  
63      @Override
64      public SortedSet<E> subSet(E fromElement, E toElement) {
65        return multiset().subMultiset(fromElement, CLOSED, toElement, OPEN).elementSet();
66      }
67  
68      @Override
69      public SortedSet<E> headSet(E toElement) {
70        return multiset().headMultiset(toElement, OPEN).elementSet();
71      }
72  
73      @Override
74      public SortedSet<E> tailSet(E fromElement) {
75        return multiset().tailMultiset(fromElement, CLOSED).elementSet();
76      }
77  
78      @Override
79      public E first() {
80        return getElementOrThrow(multiset().firstEntry());
81      }
82  
83      @Override
84      public E last() {
85        return getElementOrThrow(multiset().lastEntry());
86      }
87    }
88  
89    /**
90     * A skeleton navigable implementation for {@link SortedMultiset#elementSet}.
91     */
92    @GwtIncompatible // Navigable
93    static class NavigableElementSet<E> extends ElementSet<E> implements NavigableSet<E> {
94      NavigableElementSet(SortedMultiset<E> multiset) {
95        super(multiset);
96      }
97  
98      @Override
99      public E lower(E e) {
100       return getElementOrNull(multiset().headMultiset(e, OPEN).lastEntry());
101     }
102 
103     @Override
104     public E floor(E e) {
105       return getElementOrNull(multiset().headMultiset(e, CLOSED).lastEntry());
106     }
107 
108     @Override
109     public E ceiling(E e) {
110       return getElementOrNull(multiset().tailMultiset(e, CLOSED).firstEntry());
111     }
112 
113     @Override
114     public E higher(E e) {
115       return getElementOrNull(multiset().tailMultiset(e, OPEN).firstEntry());
116     }
117 
118     @Override
119     public NavigableSet<E> descendingSet() {
120       return new NavigableElementSet<E>(multiset().descendingMultiset());
121     }
122 
123     @Override
124     public Iterator<E> descendingIterator() {
125       return descendingSet().iterator();
126     }
127 
128     @Override
129     public E pollFirst() {
130       return getElementOrNull(multiset().pollFirstEntry());
131     }
132 
133     @Override
134     public E pollLast() {
135       return getElementOrNull(multiset().pollLastEntry());
136     }
137 
138     @Override
139     public NavigableSet<E> subSet(
140         E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) {
141       return new NavigableElementSet<E>(
142           multiset()
143               .subMultiset(
144                   fromElement, BoundType.forBoolean(fromInclusive),
145                   toElement, BoundType.forBoolean(toInclusive)));
146     }
147 
148     @Override
149     public NavigableSet<E> headSet(E toElement, boolean inclusive) {
150       return new NavigableElementSet<E>(
151           multiset().headMultiset(toElement, BoundType.forBoolean(inclusive)));
152     }
153 
154     @Override
155     public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
156       return new NavigableElementSet<E>(
157           multiset().tailMultiset(fromElement, BoundType.forBoolean(inclusive)));
158     }
159   }
160 
161   private static <E> E getElementOrThrow(Entry<E> entry) {
162     if (entry == null) {
163       throw new NoSuchElementException();
164     }
165     return entry.getElement();
166   }
167 
168   private static <E> E getElementOrNull(@Nullable Entry<E> entry) {
169     return (entry == null) ? null : entry.getElement();
170   }
171 }