• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of 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,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.collect;
18 
19 import com.google.common.annotations.Beta;
20 
21 import java.util.Iterator;
22 import java.util.NavigableSet;
23 import java.util.SortedSet;
24 
25 /**
26  * A navigable set which forwards all its method calls to another navigable set. Subclasses should
27  * override one or more methods to modify the behavior of the backing set as desired per the <a
28  * href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>.
29  *
30  * <p><i>Warning:</i> The methods of {@code ForwardingNavigableSet} forward <i>indiscriminately</i>
31  * to the methods of the delegate. For example, overriding {@link #add} alone <i>will not</i>
32  * change the behavior of {@link #addAll}, which can lead to unexpected behavior. In this case, you
33  * should override {@code addAll} as well, either providing your own implementation, or delegating
34  * to the provided {@code standardAddAll} method.
35  *
36  * <p>Each of the {@code standard} methods uses the set's comparator (or the natural ordering of
37  * the elements, if there is no comparator) to test element equality. As a result, if the
38  * comparator is not consistent with equals, some of the standard implementations may violate the
39  * {@code Set} contract.
40  *
41  * <p>The {@code standard} methods and the collection views they return are not guaranteed to be
42  * thread-safe, even when all of the methods that they depend on are thread-safe.
43  *
44  * @author Louis Wasserman
45  * @since 12.0
46  */
47 public abstract class ForwardingNavigableSet<E>
48     extends ForwardingSortedSet<E> implements NavigableSet<E> {
49 
50   /** Constructor for use by subclasses. */
ForwardingNavigableSet()51   protected ForwardingNavigableSet() {}
52 
53   @Override
delegate()54   protected abstract NavigableSet<E> delegate();
55 
56   @Override
lower(E e)57   public E lower(E e) {
58     return delegate().lower(e);
59   }
60 
61   /**
62    * A sensible definition of {@link #lower} in terms of the {@code descendingIterator} method of
63    * {@link #headSet(Object, boolean)}. If you override {@link #headSet(Object, boolean)}, you may
64    * wish to override {@link #lower} to forward to this implementation.
65    */
standardLower(E e)66   protected E standardLower(E e) {
67     return Iterators.getNext(headSet(e, false).descendingIterator(), null);
68   }
69 
70   @Override
floor(E e)71   public E floor(E e) {
72     return delegate().floor(e);
73   }
74 
75   /**
76    * A sensible definition of {@link #floor} in terms of the {@code descendingIterator} method of
77    * {@link #headSet(Object, boolean)}. If you override {@link #headSet(Object, boolean)}, you may
78    * wish to override {@link #floor} to forward to this implementation.
79    */
standardFloor(E e)80   protected E standardFloor(E e) {
81     return Iterators.getNext(headSet(e, true).descendingIterator(), null);
82   }
83 
84   @Override
ceiling(E e)85   public E ceiling(E e) {
86     return delegate().ceiling(e);
87   }
88 
89   /**
90    * A sensible definition of {@link #ceiling} in terms of the {@code iterator} method of
91    * {@link #tailSet(Object, boolean)}. If you override {@link #tailSet(Object, boolean)}, you may
92    * wish to override {@link #ceiling} to forward to this implementation.
93    */
standardCeiling(E e)94   protected E standardCeiling(E e) {
95     return Iterators.getNext(tailSet(e, true).iterator(), null);
96   }
97 
98   @Override
higher(E e)99   public E higher(E e) {
100     return delegate().higher(e);
101   }
102 
103   /**
104    * A sensible definition of {@link #higher} in terms of the {@code iterator} method of
105    * {@link #tailSet(Object, boolean)}. If you override {@link #tailSet(Object, boolean)}, you may
106    * wish to override {@link #higher} to forward to this implementation.
107    */
standardHigher(E e)108   protected E standardHigher(E e) {
109     return Iterators.getNext(tailSet(e, false).iterator(), null);
110   }
111 
112   @Override
pollFirst()113   public E pollFirst() {
114     return delegate().pollFirst();
115   }
116 
117   /**
118    * A sensible definition of {@link #pollFirst} in terms of the {@code iterator} method. If you
119    * override {@link #iterator} you may wish to override {@link #pollFirst} to forward to this
120    * implementation.
121    */
standardPollFirst()122   protected E standardPollFirst() {
123     return Iterators.pollNext(iterator());
124   }
125 
126   @Override
pollLast()127   public E pollLast() {
128     return delegate().pollLast();
129   }
130 
131   /**
132    * A sensible definition of {@link #pollLast} in terms of the {@code descendingIterator} method.
133    * If you override {@link #descendingIterator} you may wish to override {@link #pollLast} to
134    * forward to this implementation.
135    */
standardPollLast()136   protected E standardPollLast() {
137     return Iterators.pollNext(descendingIterator());
138   }
139 
standardFirst()140   protected E standardFirst() {
141     return iterator().next();
142   }
143 
standardLast()144   protected E standardLast() {
145     return descendingIterator().next();
146   }
147 
148   @Override
descendingSet()149   public NavigableSet<E> descendingSet() {
150     return delegate().descendingSet();
151   }
152 
153   /**
154    * A sensible implementation of {@link NavigableSet#descendingSet} in terms of the other methods
155    * of {@link NavigableSet}, notably including {@link NavigableSet#descendingIterator}.
156    *
157    * <p>In many cases, you may wish to override {@link ForwardingNavigableSet#descendingSet} to
158    * forward to this implementation or a subclass thereof.
159    *
160    * @since 12.0
161    */
162   @Beta
163   protected class StandardDescendingSet extends Sets.DescendingSet<E> {
164     /** Constructor for use by subclasses. */
StandardDescendingSet()165     public StandardDescendingSet() {
166       super(ForwardingNavigableSet.this);
167     }
168   }
169 
170   @Override
descendingIterator()171   public Iterator<E> descendingIterator() {
172     return delegate().descendingIterator();
173   }
174 
175   @Override
subSet( E fromElement, boolean fromInclusive, E toElement, boolean toInclusive)176   public NavigableSet<E> subSet(
177       E fromElement,
178       boolean fromInclusive,
179       E toElement,
180       boolean toInclusive) {
181     return delegate().subSet(fromElement, fromInclusive, toElement, toInclusive);
182   }
183 
184   /**
185    * A sensible definition of {@link #subSet(Object, boolean, Object, boolean)} in terms of the
186    * {@code headSet} and {@code tailSet} methods. In many cases, you may wish to override
187    * {@link #subSet(Object, boolean, Object, boolean)} to forward to this implementation.
188    */
189   @Beta
standardSubSet( E fromElement, boolean fromInclusive, E toElement, boolean toInclusive)190   protected NavigableSet<E> standardSubSet(
191       E fromElement,
192       boolean fromInclusive,
193       E toElement,
194       boolean toInclusive) {
195     return tailSet(fromElement, fromInclusive).headSet(toElement, toInclusive);
196   }
197 
198   /**
199    * A sensible definition of {@link #subSet(Object, Object)} in terms of the
200    * {@link #subSet(Object, boolean, Object, boolean)} method. If you override
201    * {@link #subSet(Object, boolean, Object, boolean)}, you may wish to override
202    * {@link #subSet(Object, Object)} to forward to this implementation.
203    */
204   @Override
standardSubSet(E fromElement, E toElement)205   protected SortedSet<E> standardSubSet(E fromElement, E toElement) {
206     return subSet(fromElement, true, toElement, false);
207   }
208 
209   @Override
headSet(E toElement, boolean inclusive)210   public NavigableSet<E> headSet(E toElement, boolean inclusive) {
211     return delegate().headSet(toElement, inclusive);
212   }
213 
214   /**
215    * A sensible definition of {@link #headSet(Object)} in terms of the
216    * {@link #headSet(Object, boolean)} method. If you override
217    * {@link #headSet(Object, boolean)}, you may wish to override
218    * {@link #headSet(Object)} to forward to this implementation.
219    */
standardHeadSet(E toElement)220   protected SortedSet<E> standardHeadSet(E toElement) {
221     return headSet(toElement, false);
222   }
223 
224   @Override
tailSet(E fromElement, boolean inclusive)225   public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
226     return delegate().tailSet(fromElement, inclusive);
227   }
228 
229   /**
230    * A sensible definition of {@link #tailSet(Object)} in terms of the
231    * {@link #tailSet(Object, boolean)} method. If you override
232    * {@link #tailSet(Object, boolean)}, you may wish to override
233    * {@link #tailSet(Object)} to forward to this implementation.
234    */
standardTailSet(E fromElement)235   protected SortedSet<E> standardTailSet(E fromElement) {
236     return tailSet(fromElement, true);
237   }
238 }
239