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