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