Coverage Summary for Class: SafeTreeMap (com.google.common.collect.testing)

Class Method, % Line, %
SafeTreeMap 93.6% (44/47) 91.5% (65/71)
SafeTreeMap$1 100% (2/2) 100% (2/2)
SafeTreeMap$2 100% (7/7) 100% (10/10)
Total 94.6% (53/56) 92.8% (77/83)


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.AbstractSet; 22 import java.util.Collection; 23 import java.util.Comparator; 24 import java.util.Iterator; 25 import java.util.Map; 26 import java.util.NavigableMap; 27 import java.util.NavigableSet; 28 import java.util.Set; 29 import java.util.SortedMap; 30 import java.util.TreeMap; 31  32 /** 33  * A wrapper around {@code TreeMap} that aggressively checks to see if keys are mutually comparable. 34  * This implementation passes the navigable map test suites. 35  * 36  * @author Louis Wasserman 37  */ 38 @GwtIncompatible 39 public final class SafeTreeMap<K, V> implements Serializable, NavigableMap<K, V> { 40  @SuppressWarnings("unchecked") 41  private static final Comparator<Object> NATURAL_ORDER = 42  new Comparator<Object>() { 43  @Override 44  public int compare(Object o1, Object o2) { 45  return ((Comparable<Object>) o1).compareTo(o2); 46  } 47  }; 48  49  private final NavigableMap<K, V> delegate; 50  51  public SafeTreeMap() { 52  this(new TreeMap<K, V>()); 53  } 54  55  public SafeTreeMap(Comparator<? super K> comparator) { 56  this(new TreeMap<K, V>(comparator)); 57  } 58  59  public SafeTreeMap(Map<? extends K, ? extends V> map) { 60  this(new TreeMap<K, V>(map)); 61  } 62  63  public SafeTreeMap(SortedMap<K, ? extends V> map) { 64  this(new TreeMap<K, V>(map)); 65  } 66  67  private SafeTreeMap(NavigableMap<K, V> delegate) { 68  this.delegate = delegate; 69  if (delegate == null) { 70  throw new NullPointerException(); 71  } 72  for (K k : keySet()) { 73  checkValid(k); 74  } 75  } 76  77  @Override 78  public Entry<K, V> ceilingEntry(K key) { 79  return delegate.ceilingEntry(checkValid(key)); 80  } 81  82  @Override 83  public K ceilingKey(K key) { 84  return delegate.ceilingKey(checkValid(key)); 85  } 86  87  @Override 88  public void clear() { 89  delegate.clear(); 90  } 91  92  @SuppressWarnings("unchecked") 93  @Override 94  public Comparator<? super K> comparator() { 95  Comparator<? super K> comparator = delegate.comparator(); 96  if (comparator == null) { 97  comparator = (Comparator<? super K>) NATURAL_ORDER; 98  } 99  return comparator; 100  } 101  102  @Override 103  public boolean containsKey(Object key) { 104  try { 105  return delegate.containsKey(checkValid(key)); 106  } catch (NullPointerException | ClassCastException e) { 107  return false; 108  } 109  } 110  111  @Override 112  public boolean containsValue(Object value) { 113  return delegate.containsValue(value); 114  } 115  116  @Override 117  public NavigableSet<K> descendingKeySet() { 118  return delegate.descendingKeySet(); 119  } 120  121  @Override 122  public NavigableMap<K, V> descendingMap() { 123  return new SafeTreeMap<>(delegate.descendingMap()); 124  } 125  126  @Override 127  public Set<Entry<K, V>> entrySet() { 128  return new AbstractSet<Entry<K, V>>() { 129  private Set<Entry<K, V>> delegate() { 130  return delegate.entrySet(); 131  } 132  133  @Override 134  public boolean contains(Object object) { 135  try { 136  return delegate().contains(object); 137  } catch (NullPointerException | ClassCastException e) { 138  return false; 139  } 140  } 141  142  @Override 143  public Iterator<Entry<K, V>> iterator() { 144  return delegate().iterator(); 145  } 146  147  @Override 148  public int size() { 149  return delegate().size(); 150  } 151  152  @Override 153  public boolean remove(Object o) { 154  return delegate().remove(o); 155  } 156  157  @Override 158  public void clear() { 159  delegate().clear(); 160  } 161  }; 162  } 163  164  @Override 165  public Entry<K, V> firstEntry() { 166  return delegate.firstEntry(); 167  } 168  169  @Override 170  public K firstKey() { 171  return delegate.firstKey(); 172  } 173  174  @Override 175  public Entry<K, V> floorEntry(K key) { 176  return delegate.floorEntry(checkValid(key)); 177  } 178  179  @Override 180  public K floorKey(K key) { 181  return delegate.floorKey(checkValid(key)); 182  } 183  184  @Override 185  public V get(Object key) { 186  return delegate.get(checkValid(key)); 187  } 188  189  @Override 190  public SortedMap<K, V> headMap(K toKey) { 191  return headMap(toKey, false); 192  } 193  194  @Override 195  public NavigableMap<K, V> headMap(K toKey, boolean inclusive) { 196  return new SafeTreeMap<>(delegate.headMap(checkValid(toKey), inclusive)); 197  } 198  199  @Override 200  public Entry<K, V> higherEntry(K key) { 201  return delegate.higherEntry(checkValid(key)); 202  } 203  204  @Override 205  public K higherKey(K key) { 206  return delegate.higherKey(checkValid(key)); 207  } 208  209  @Override 210  public boolean isEmpty() { 211  return delegate.isEmpty(); 212  } 213  214  @Override 215  public NavigableSet<K> keySet() { 216  return navigableKeySet(); 217  } 218  219  @Override 220  public Entry<K, V> lastEntry() { 221  return delegate.lastEntry(); 222  } 223  224  @Override 225  public K lastKey() { 226  return delegate.lastKey(); 227  } 228  229  @Override 230  public Entry<K, V> lowerEntry(K key) { 231  return delegate.lowerEntry(checkValid(key)); 232  } 233  234  @Override 235  public K lowerKey(K key) { 236  return delegate.lowerKey(checkValid(key)); 237  } 238  239  @Override 240  public NavigableSet<K> navigableKeySet() { 241  return delegate.navigableKeySet(); 242  } 243  244  @Override 245  public Entry<K, V> pollFirstEntry() { 246  return delegate.pollFirstEntry(); 247  } 248  249  @Override 250  public Entry<K, V> pollLastEntry() { 251  return delegate.pollLastEntry(); 252  } 253  254  @Override 255  public V put(K key, V value) { 256  return delegate.put(checkValid(key), value); 257  } 258  259  @Override 260  public void putAll(Map<? extends K, ? extends V> map) { 261  for (K key : map.keySet()) { 262  checkValid(key); 263  } 264  delegate.putAll(map); 265  } 266  267  @Override 268  public V remove(Object key) { 269  return delegate.remove(checkValid(key)); 270  } 271  272  @Override 273  public int size() { 274  return delegate.size(); 275  } 276  277  @Override 278  public NavigableMap<K, V> subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) { 279  return new SafeTreeMap<>( 280  delegate.subMap(checkValid(fromKey), fromInclusive, checkValid(toKey), toInclusive)); 281  } 282  283  @Override 284  public SortedMap<K, V> subMap(K fromKey, K toKey) { 285  return subMap(fromKey, true, toKey, false); 286  } 287  288  @Override 289  public SortedMap<K, V> tailMap(K fromKey) { 290  return tailMap(fromKey, true); 291  } 292  293  @Override 294  public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) { 295  return new SafeTreeMap<>(delegate.tailMap(checkValid(fromKey), inclusive)); 296  } 297  298  @Override 299  public Collection<V> values() { 300  return delegate.values(); 301  } 302  303  private <T> T checkValid(T t) { 304  // a ClassCastException is what's supposed to happen! 305  @SuppressWarnings("unchecked") 306  K k = (K) t; 307  comparator().compare(k, k); 308  return t; 309  } 310  311  @Override 312  public boolean equals(Object obj) { 313  return delegate.equals(obj); 314  } 315  316  @Override 317  public int hashCode() { 318  return delegate.hashCode(); 319  } 320  321  @Override 322  public String toString() { 323  return delegate.toString(); 324  } 325  326  private static final long serialVersionUID = 0L; 327 }