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}