001/*
002 * Copyright (C) 2012 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package com.google.common.collect;
018
019import com.google.common.annotations.Beta;
020import com.google.common.annotations.GwtIncompatible;
021import java.util.Iterator;
022import java.util.NavigableSet;
023import java.util.SortedSet;
024import javax.annotation.CheckForNull;
025import org.checkerframework.checker.nullness.qual.Nullable;
026
027/**
028 * A navigable set which forwards all its method calls to another navigable set. Subclasses should
029 * override one or more methods to modify the behavior of the backing set as desired per the <a
030 * href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>.
031 *
032 * <p><b>Warning:</b> The methods of {@code ForwardingNavigableSet} forward <i>indiscriminately</i>
033 * to the methods of the delegate. For example, overriding {@link #add} alone <i>will not</i> change
034 * the behavior of {@link #addAll}, which can lead to unexpected behavior. In this case, you should
035 * override {@code addAll} as well, either providing your own implementation, or delegating to the
036 * provided {@code standardAddAll} method.
037 *
038 * <p><b>{@code default} method warning:</b> This class does <i>not</i> forward calls to {@code
039 * default} methods. Instead, it inherits their default implementations. When those implementations
040 * invoke methods, they invoke methods on the {@code ForwardingNavigableSet}.
041 *
042 * <p>Each of the {@code standard} methods uses the set's comparator (or the natural ordering of the
043 * elements, if there is no comparator) to test element equality. As a result, if the comparator is
044 * not consistent with equals, some of the standard implementations may violate the {@code Set}
045 * contract.
046 *
047 * <p>The {@code standard} methods and the collection views they return are not guaranteed to be
048 * thread-safe, even when all of the methods that they depend on are thread-safe.
049 *
050 * @author Louis Wasserman
051 * @since 12.0
052 */
053@GwtIncompatible
054@ElementTypesAreNonnullByDefault
055public abstract class ForwardingNavigableSet<E extends @Nullable Object>
056    extends ForwardingSortedSet<E> implements NavigableSet<E> {
057
058  /** Constructor for use by subclasses. */
059  protected ForwardingNavigableSet() {}
060
061  @Override
062  protected abstract NavigableSet<E> delegate();
063
064  @Override
065  @CheckForNull
066  public E lower(@ParametricNullness E e) {
067    return delegate().lower(e);
068  }
069
070  /**
071   * A sensible definition of {@link #lower} in terms of the {@code descendingIterator} method of
072   * {@link #headSet(Object, boolean)}. If you override {@link #headSet(Object, boolean)}, you may
073   * wish to override {@link #lower} to forward to this implementation.
074   */
075  @CheckForNull
076  protected E standardLower(@ParametricNullness E e) {
077    return Iterators.getNext(headSet(e, false).descendingIterator(), null);
078  }
079
080  @Override
081  @CheckForNull
082  public E floor(@ParametricNullness E e) {
083    return delegate().floor(e);
084  }
085
086  /**
087   * A sensible definition of {@link #floor} in terms of the {@code descendingIterator} method of
088   * {@link #headSet(Object, boolean)}. If you override {@link #headSet(Object, boolean)}, you may
089   * wish to override {@link #floor} to forward to this implementation.
090   */
091  @CheckForNull
092  protected E standardFloor(@ParametricNullness E e) {
093    return Iterators.getNext(headSet(e, true).descendingIterator(), null);
094  }
095
096  @Override
097  @CheckForNull
098  public E ceiling(@ParametricNullness E e) {
099    return delegate().ceiling(e);
100  }
101
102  /**
103   * A sensible definition of {@link #ceiling} in terms of the {@code iterator} method of {@link
104   * #tailSet(Object, boolean)}. If you override {@link #tailSet(Object, boolean)}, you may wish to
105   * override {@link #ceiling} to forward to this implementation.
106   */
107  @CheckForNull
108  protected E standardCeiling(@ParametricNullness E e) {
109    return Iterators.getNext(tailSet(e, true).iterator(), null);
110  }
111
112  @Override
113  @CheckForNull
114  public E higher(@ParametricNullness E e) {
115    return delegate().higher(e);
116  }
117
118  /**
119   * A sensible definition of {@link #higher} in terms of the {@code iterator} method of {@link
120   * #tailSet(Object, boolean)}. If you override {@link #tailSet(Object, boolean)}, you may wish to
121   * override {@link #higher} to forward to this implementation.
122   */
123  @CheckForNull
124  protected E standardHigher(@ParametricNullness E e) {
125    return Iterators.getNext(tailSet(e, false).iterator(), null);
126  }
127
128  @Override
129  @CheckForNull
130  public E pollFirst() {
131    return delegate().pollFirst();
132  }
133
134  /**
135   * A sensible definition of {@link #pollFirst} in terms of the {@code iterator} method. If you
136   * override {@link #iterator} you may wish to override {@link #pollFirst} to forward to this
137   * implementation.
138   */
139  @CheckForNull
140  protected E standardPollFirst() {
141    return Iterators.pollNext(iterator());
142  }
143
144  @Override
145  @CheckForNull
146  public E pollLast() {
147    return delegate().pollLast();
148  }
149
150  /**
151   * A sensible definition of {@link #pollLast} in terms of the {@code descendingIterator} method.
152   * If you override {@link #descendingIterator} you may wish to override {@link #pollLast} to
153   * forward to this implementation.
154   */
155  @CheckForNull
156  protected E standardPollLast() {
157    return Iterators.pollNext(descendingIterator());
158  }
159
160  @ParametricNullness
161  protected E standardFirst() {
162    return iterator().next();
163  }
164
165  @ParametricNullness
166  protected E standardLast() {
167    return descendingIterator().next();
168  }
169
170  @Override
171  public NavigableSet<E> descendingSet() {
172    return delegate().descendingSet();
173  }
174
175  /**
176   * A sensible implementation of {@link NavigableSet#descendingSet} in terms of the other methods
177   * of {@link NavigableSet}, notably including {@link NavigableSet#descendingIterator}.
178   *
179   * <p>In many cases, you may wish to override {@link ForwardingNavigableSet#descendingSet} to
180   * forward to this implementation or a subclass thereof.
181   *
182   * @since 12.0
183   */
184  @Beta
185  protected class StandardDescendingSet extends Sets.DescendingSet<E> {
186    /** Constructor for use by subclasses. */
187    public StandardDescendingSet() {
188      super(ForwardingNavigableSet.this);
189    }
190  }
191
192  @Override
193  public Iterator<E> descendingIterator() {
194    return delegate().descendingIterator();
195  }
196
197  @Override
198  public NavigableSet<E> subSet(
199      @ParametricNullness E fromElement,
200      boolean fromInclusive,
201      @ParametricNullness E toElement,
202      boolean toInclusive) {
203    return delegate().subSet(fromElement, fromInclusive, toElement, toInclusive);
204  }
205
206  /**
207   * A sensible definition of {@link #subSet(Object, boolean, Object, boolean)} in terms of the
208   * {@code headSet} and {@code tailSet} methods. In many cases, you may wish to override {@link
209   * #subSet(Object, boolean, Object, boolean)} to forward to this implementation.
210   */
211  @Beta
212  protected NavigableSet<E> standardSubSet(
213      @ParametricNullness E fromElement,
214      boolean fromInclusive,
215      @ParametricNullness E toElement,
216      boolean toInclusive) {
217    return tailSet(fromElement, fromInclusive).headSet(toElement, toInclusive);
218  }
219
220  /**
221   * A sensible definition of {@link #subSet(Object, Object)} in terms of the {@link #subSet(Object,
222   * boolean, Object, boolean)} method. If you override {@link #subSet(Object, boolean, Object,
223   * boolean)}, you may wish to override {@link #subSet(Object, Object)} to forward to this
224   * implementation.
225   */
226  @Override
227  protected SortedSet<E> standardSubSet(
228      @ParametricNullness E fromElement, @ParametricNullness E toElement) {
229    return subSet(fromElement, true, toElement, false);
230  }
231
232  @Override
233  public NavigableSet<E> headSet(@ParametricNullness E toElement, boolean inclusive) {
234    return delegate().headSet(toElement, inclusive);
235  }
236
237  /**
238   * A sensible definition of {@link #headSet(Object)} in terms of the {@link #headSet(Object,
239   * boolean)} method. If you override {@link #headSet(Object, boolean)}, you may wish to override
240   * {@link #headSet(Object)} to forward to this implementation.
241   */
242  protected SortedSet<E> standardHeadSet(@ParametricNullness E toElement) {
243    return headSet(toElement, false);
244  }
245
246  @Override
247  public NavigableSet<E> tailSet(@ParametricNullness E fromElement, boolean inclusive) {
248    return delegate().tailSet(fromElement, inclusive);
249  }
250
251  /**
252   * A sensible definition of {@link #tailSet(Object)} in terms of the {@link #tailSet(Object,
253   * boolean)} method. If you override {@link #tailSet(Object, boolean)}, you may wish to override
254   * {@link #tailSet(Object)} to forward to this implementation.
255   */
256  protected SortedSet<E> standardTailSet(@ParametricNullness E fromElement) {
257    return tailSet(fromElement, true);
258  }
259}