    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
    017    package com.google.common.collect;
    018
    019    import com.google.common.annotations.Beta;
    020
    021    import java.util.Iterator;
    022    import java.util.NavigableSet;
    023    import java.util.SortedSet;
    024
    025    import javax.annotation.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><i>Warning:</i> 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>
    034     * change the behavior of {@link #addAll}, which can lead to unexpected behavior. In this case, you
    035     * should override {@code addAll} as well, either providing your own implementation, or delegating
    036     * to the provided {@code standardAddAll} method.
    037     *
    038     * <p>Each of the {@code standard} methods uses the set's comparator (or the natural ordering of
    039     * the elements, if there is no comparator) to test element equality. As a result, if the
    040     * comparator is not consistent with equals, some of the standard implementations may violate the
    041     * {@code Set} contract.
    042     *
    043     * <p>The {@code standard} methods and the collection views they return are not guaranteed to be
    044     * thread-safe, even when all of the methods that they depend on are thread-safe.
    045     *
    046     * @author Louis Wasserman
    047     * @since 12.0
    048     */
    049    @Beta
    050    public abstract class ForwardingNavigableSet<E>
    051        extends ForwardingSortedSet<E> implements NavigableSet<E> {
    052
    053      /** Constructor for use by subclasses. */
    054      protected ForwardingNavigableSet() {}
    055
    056      @Override
    057      protected abstract NavigableSet<E> delegate();
    058
    059      @Override
    060      public E lower(E e) {
    061        return delegate().lower(e);
    062      }
    063
    064      /**
    065       * A sensible definition of {@link #lower} in terms of the {@code descendingIterator} method of
    066       * {@link #headSet(Object, boolean)}. If you override {@link #headSet(Object, boolean)}, you may
    067       * wish to override {@link #lower} to forward to this implementation.
    068       */
    069      protected E standardLower(E e) {
    070        return Iterators.getNext(headSet(e, false).descendingIterator(), null);
    071      }
    072
    073      @Override
    074      public E floor(E e) {
    075        return delegate().floor(e);
    076      }
    077
    078      /**
    079       * A sensible definition of {@link #floor} in terms of the {@code descendingIterator} method of
    080       * {@link #headSet(Object, boolean)}. If you override {@link #headSet(Object, boolean)}, you may
    081       * wish to override {@link #floor} to forward to this implementation.
    082       */
    083      protected E standardFloor(E e) {
    084        return Iterators.getNext(headSet(e, true).descendingIterator(), null);
    085      }
    086
    087      @Override
    088      public E ceiling(E e) {
    089        return delegate().ceiling(e);
    090      }
    091
    092      /**
    093       * A sensible definition of {@link #ceiling} in terms of the {@code iterator} method of
    094       * {@link #tailSet(Object, boolean)}. If you override {@link #tailSet(Object, boolean)}, you may
    095       * wish to override {@link #ceiling} to forward to this implementation.
    096       */
    097      protected E standardCeiling(E e) {
    098        return Iterators.getNext(tailSet(e, true).iterator(), null);
    099      }
    100
    101      @Override
    102      public E higher(E e) {
    103        return delegate().higher(e);
    104      }
    105
    106      /**
    107       * A sensible definition of {@link #higher} in terms of the {@code iterator} method of
    108       * {@link #tailSet(Object, boolean)}. If you override {@link #tailSet(Object, boolean)}, you may
    109       * wish to override {@link #higher} to forward to this implementation.
    110       */
    111      protected E standardHigher(E e) {
    112        return Iterators.getNext(tailSet(e, false).iterator(), null);
    113      }
    114
    115      @Override
    116      public E pollFirst() {
    117        return delegate().pollFirst();
    118      }
    119
    120      /**
    121       * A sensible definition of {@link #pollFirst} in terms of the {@code iterator} method. If you
    122       * override {@link #iterator} you may wish to override {@link #pollFirst} to forward to this
    123       * implementation.
    124       */
    125      protected E standardPollFirst() {
    126        return poll(iterator());
    127      }
    128
    129      @Override
    130      public E pollLast() {
    131        return delegate().pollLast();
    132      }
    133
    134      /**
    135       * A sensible definition of {@link #pollLast} in terms of the {@code descendingIterator} method.
    136       * If you override {@link #descendingIterator} you may wish to override {@link #pollLast} to
    137       * forward to this implementation.
    138       */
    139      protected E standardPollLast() {
    140        return poll(delegate().descendingIterator());
    141      }
    142
    143      protected E standardFirst() {
    144        return iterator().next();
    145      }
    146
    147      protected E standardLast() {
    148        return descendingIterator().next();
    149      }
    150
    151      @Override
    152      public NavigableSet<E> descendingSet() {
    153        return delegate().descendingSet();
    154      }
    155
    156      /**
    157       * A sensible implementation of {@link NavigableSet#descendingSet} in terms of the other methods
    158       * of {@link NavigableSet}, notably including {@link NavigableSet#descendingIterator}.
    159       *
    160       * <p>In many cases, you may wish to override {@link ForwardingNavigableSet#descendingSet} to
    161       * forward to this implementation or a subclass thereof.
    162       *
    163       * @since 12.0
    164       */
    165      @Beta
    166      protected class StandardDescendingSet extends Sets.DescendingSet<E> {
    167        /** Constructor for use by subclasses. */
    168        public StandardDescendingSet() {
    169          super(ForwardingNavigableSet.this);
    170        }
    171      }
    172
    173      @Override
    174      public Iterator<E> descendingIterator() {
    175        return delegate().descendingIterator();
    176      }
    177
    178      @Override
    179      public NavigableSet<E> subSet(
    180          E fromElement,
    181          boolean fromInclusive,
    182          E toElement,
    183          boolean toInclusive) {
    184        return delegate().subSet(fromElement, fromInclusive, toElement, toInclusive);
    185      }
    186
    187      /**
    188       * A sensible definition of {@link #subSet(Object, boolean, Object, boolean)} in terms of the
    189       * {@code headSet} and {@code tailSet} methods. In many cases, you may wish to override
    190       * {@link #subSet(Object, boolean, Object, boolean)} to forward to this implementation.
    191       */
    192      protected NavigableSet<E> standardSubSet(
    193          E fromElement,
    194          boolean fromInclusive,
    195          E toElement,
    196          boolean toInclusive) {
    197        return tailSet(fromElement, fromInclusive).headSet(toElement, toInclusive);
    198      }
    199
    200      /**
    201       * A sensible definition of {@link #subSet(Object, Object)} in terms of the
    202       * {@link #subSet(Object, boolean, Object, boolean)} method. If you override
    203       * {@link #subSet(Object, boolean, Object, boolean)}, you may wish to override
    204       * {@link #subSet(Object, Object)} to forward to this implementation.
    205       */
    206      @Override
    207      protected SortedSet<E> standardSubSet(E fromElement, E toElement) {
    208        return subSet(fromElement, true, toElement, false);
    209      }
    210
    211      @Override
    212      public NavigableSet<E> headSet(E toElement, boolean inclusive) {
    213        return delegate().headSet(toElement, inclusive);
    214      }
    215
    216      /**
    217       * A sensible definition of {@link #headSet(Object)} in terms of the
    218       * {@link #headSet(Object, boolean)} method. If you override
    219       * {@link #headSet(Object, boolean)}, you may wish to override
    220       * {@link #headSet(Object)} to forward to this implementation.
    221       */
    222      protected SortedSet<E> standardHeadSet(E toElement) {
    223        return headSet(toElement, false);
    224      }
    225
    226      @Override
    227      public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
    228        return delegate().tailSet(fromElement, inclusive);
    229      }
    230
    231      /**
    232       * A sensible definition of {@link #tailSet(Object)} in terms of the
    233       * {@link #tailSet(Object, boolean)} method. If you override
    234       * {@link #tailSet(Object, boolean)}, you may wish to override
    235       * {@link #tailSet(Object)} to forward to this implementation.
    236       */
    237      protected SortedSet<E> standardTailSet(E fromElement) {
    238        return tailSet(fromElement, true);
    239      }
    240
    241      @Nullable
    242      private E poll(Iterator<E> iterator) {
    243        if (iterator.hasNext()) {
    244          E result = iterator.next();
    245          iterator.remove();
    246          return result;
    247        }
    248        return null;
    249      }
    250    }