• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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.testing;
18 
19 import com.google.common.annotations.GwtIncompatible;
20 import java.io.Serializable;
21 import java.util.Collection;
22 import java.util.Comparator;
23 import java.util.Iterator;
24 import java.util.NavigableSet;
25 import java.util.SortedSet;
26 import java.util.TreeSet;
27 
28 /**
29  * A wrapper around {@code TreeSet} that aggressively checks to see if elements are mutually
30  * comparable. This implementation passes the navigable set test suites.
31  *
32  * @author Louis Wasserman
33  */
34 @GwtIncompatible
35 public final class SafeTreeSet<E> implements Serializable, NavigableSet<E> {
36   @SuppressWarnings("unchecked")
37   private static final Comparator<Object> NATURAL_ORDER =
38       new Comparator<Object>() {
39         @Override
40         public int compare(Object o1, Object o2) {
41           return ((Comparable<Object>) o1).compareTo(o2);
42         }
43       };
44 
45   private final NavigableSet<E> delegate;
46 
SafeTreeSet()47   public SafeTreeSet() {
48     this(new TreeSet<E>());
49   }
50 
SafeTreeSet(Collection<? extends E> collection)51   public SafeTreeSet(Collection<? extends E> collection) {
52     this(new TreeSet<E>(collection));
53   }
54 
SafeTreeSet(Comparator<? super E> comparator)55   public SafeTreeSet(Comparator<? super E> comparator) {
56     this(new TreeSet<E>(comparator));
57   }
58 
SafeTreeSet(SortedSet<E> set)59   public SafeTreeSet(SortedSet<E> set) {
60     this(new TreeSet<E>(set));
61   }
62 
SafeTreeSet(NavigableSet<E> delegate)63   private SafeTreeSet(NavigableSet<E> delegate) {
64     this.delegate = delegate;
65     for (E e : this) {
66       checkValid(e);
67     }
68   }
69 
70   @Override
add(E element)71   public boolean add(E element) {
72     return delegate.add(checkValid(element));
73   }
74 
75   @Override
addAll(Collection<? extends E> collection)76   public boolean addAll(Collection<? extends E> collection) {
77     for (E e : collection) {
78       checkValid(e);
79     }
80     return delegate.addAll(collection);
81   }
82 
83   @Override
ceiling(E e)84   public E ceiling(E e) {
85     return delegate.ceiling(checkValid(e));
86   }
87 
88   @Override
clear()89   public void clear() {
90     delegate.clear();
91   }
92 
93   @SuppressWarnings("unchecked")
94   @Override
comparator()95   public Comparator<? super E> comparator() {
96     Comparator<? super E> comparator = delegate.comparator();
97     if (comparator == null) {
98       comparator = (Comparator<? super E>) NATURAL_ORDER;
99     }
100     return comparator;
101   }
102 
103   @Override
contains(Object object)104   public boolean contains(Object object) {
105     return delegate.contains(checkValid(object));
106   }
107 
108   @Override
containsAll(Collection<?> c)109   public boolean containsAll(Collection<?> c) {
110     return delegate.containsAll(c);
111   }
112 
113   @Override
descendingIterator()114   public Iterator<E> descendingIterator() {
115     return delegate.descendingIterator();
116   }
117 
118   @Override
descendingSet()119   public NavigableSet<E> descendingSet() {
120     return new SafeTreeSet<E>(delegate.descendingSet());
121   }
122 
123   @Override
first()124   public E first() {
125     return delegate.first();
126   }
127 
128   @Override
floor(E e)129   public E floor(E e) {
130     return delegate.floor(checkValid(e));
131   }
132 
133   @Override
headSet(E toElement)134   public SortedSet<E> headSet(E toElement) {
135     return headSet(toElement, false);
136   }
137 
138   @Override
headSet(E toElement, boolean inclusive)139   public NavigableSet<E> headSet(E toElement, boolean inclusive) {
140     return new SafeTreeSet<E>(delegate.headSet(checkValid(toElement), inclusive));
141   }
142 
143   @Override
higher(E e)144   public E higher(E e) {
145     return delegate.higher(checkValid(e));
146   }
147 
148   @Override
isEmpty()149   public boolean isEmpty() {
150     return delegate.isEmpty();
151   }
152 
153   @Override
iterator()154   public Iterator<E> iterator() {
155     return delegate.iterator();
156   }
157 
158   @Override
last()159   public E last() {
160     return delegate.last();
161   }
162 
163   @Override
lower(E e)164   public E lower(E e) {
165     return delegate.lower(checkValid(e));
166   }
167 
168   @Override
pollFirst()169   public E pollFirst() {
170     return delegate.pollFirst();
171   }
172 
173   @Override
pollLast()174   public E pollLast() {
175     return delegate.pollLast();
176   }
177 
178   @Override
remove(Object object)179   public boolean remove(Object object) {
180     return delegate.remove(checkValid(object));
181   }
182 
183   @Override
removeAll(Collection<?> c)184   public boolean removeAll(Collection<?> c) {
185     return delegate.removeAll(c);
186   }
187 
188   @Override
retainAll(Collection<?> c)189   public boolean retainAll(Collection<?> c) {
190     return delegate.retainAll(c);
191   }
192 
193   @Override
size()194   public int size() {
195     return delegate.size();
196   }
197 
198   @Override
subSet( E fromElement, boolean fromInclusive, E toElement, boolean toInclusive)199   public NavigableSet<E> subSet(
200       E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) {
201     return new SafeTreeSet<E>(
202         delegate.subSet(
203             checkValid(fromElement), fromInclusive, checkValid(toElement), toInclusive));
204   }
205 
206   @Override
subSet(E fromElement, E toElement)207   public SortedSet<E> subSet(E fromElement, E toElement) {
208     return subSet(fromElement, true, toElement, false);
209   }
210 
211   @Override
tailSet(E fromElement)212   public SortedSet<E> tailSet(E fromElement) {
213     return tailSet(fromElement, true);
214   }
215 
216   @Override
tailSet(E fromElement, boolean inclusive)217   public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
218     return new SafeTreeSet<E>(delegate.tailSet(checkValid(fromElement), inclusive));
219   }
220 
221   @Override
toArray()222   public Object[] toArray() {
223     return delegate.toArray();
224   }
225 
226   @Override
toArray(T[] a)227   public <T> T[] toArray(T[] a) {
228     return delegate.toArray(a);
229   }
230 
checkValid(T t)231   private <T> T checkValid(T t) {
232     // a ClassCastException is what's supposed to happen!
233     @SuppressWarnings("unchecked")
234     E e = (E) t;
235     comparator().compare(e, e);
236     return t;
237   }
238 
239   @Override
equals(Object obj)240   public boolean equals(Object obj) {
241     return delegate.equals(obj);
242   }
243 
244   @Override
hashCode()245   public int hashCode() {
246     return delegate.hashCode();
247   }
248 
249   @Override
toString()250   public String toString() {
251     return delegate.toString();
252   }
253 
254   private static final long serialVersionUID = 0L;
255 }
256