ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/TreeMap.java
(Generate patch)

Comparing jsr166/src/main/java/util/TreeMap.java (file contents):
Revision 1.32 by dl, Sat Apr 22 16:38:01 2006 UTC vs.
Revision 1.51 by jsr166, Mon Sep 27 19:15:15 2010 UTC

# Line 1 | Line 1
1   /*
2 < * %W% %E%
2 > * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
3 > * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4   *
5 < * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
6 < * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
5 > * This code is free software; you can redistribute it and/or modify it
6 > * under the terms of the GNU General Public License version 2 only, as
7 > * published by the Free Software Foundation.  Sun designates this
8 > * particular file as subject to the "Classpath" exception as provided
9 > * by Sun in the LICENSE file that accompanied this code.
10 > *
11 > * This code is distributed in the hope that it will be useful, but WITHOUT
12 > * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 > * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 > * version 2 for more details (a copy is included in the LICENSE file that
15 > * accompanied this code).
16 > *
17 > * You should have received a copy of the GNU General Public License version
18 > * 2 along with this work; if not, write to the Free Software Foundation,
19 > * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 > *
21 > * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 > * or visit www.oracle.com if you need additional information or have any
23 > * questions.
24   */
25  
26   package java.util;
# Line 68 | Line 86 | package java.util;
86   * associated map using <tt>put</tt>.)
87   *
88   * <p>This class is a member of the
89 < * <a href="{@docRoot}/../guide/collections/index.html">
89 > * <a href="{@docRoot}/../technotes/guides/collections/index.html">
90   * Java Collections Framework</a>.
91   *
92   * @param <K> the type of keys maintained by this map
93   * @param <V> the type of mapped values
94   *
95   * @author  Josh Bloch and Doug Lea
78 * @version %I%, %G%
96   * @see Map
97   * @see HashMap
98   * @see Hashtable
# Line 109 | Line 126 | public class TreeMap<K,V>
126       */
127      private transient int modCount = 0;
128  
112    private void incrementSize()   { modCount++; size++; }
113    private void decrementSize()   { modCount++; size--; }
114
129      /**
130       * Constructs a new, empty tree map, using the natural ordering of its
131       * keys.  All keys inserted into the map must implement the {@link
# Line 222 | Line 236 | public class TreeMap<K,V>
236       *
237       * @param value value whose presence in this map is to be tested
238       * @return <tt>true</tt> if a mapping to <tt>value</tt> exists;
239 <     *         <tt>false</tt> otherwise
239 >     *         <tt>false</tt> otherwise
240       * @since 1.2
241       */
242      public boolean containsValue(Object value) {
243 <        return (root==null ? false :
244 <                (value==null ? valueSearchNull(root)
245 <                 : valueSearchNonNull(root, value)));
246 <    }
233 <
234 <    private boolean valueSearchNull(Entry n) {
235 <        if (n.value == null)
236 <            return true;
237 <
238 <        // Check left and right subtrees for value
239 <        return (n.left  != null && valueSearchNull(n.left)) ||
240 <            (n.right != null && valueSearchNull(n.right));
241 <    }
242 <
243 <    private boolean valueSearchNonNull(Entry n, Object value) {
244 <        // Check this node for the value
245 <        if (value.equals(n.value))
246 <            return true;
247 <
248 <        // Check left and right subtrees for value
249 <        return (n.left  != null && valueSearchNonNull(n.left, value)) ||
250 <            (n.right != null && valueSearchNonNull(n.right, value));
243 >        for (Entry<K,V> e = getFirstEntry(); e != null; e = successor(e))
244 >            if (valEquals(value, e.value))
245 >                return true;
246 >        return false;
247      }
248  
249      /**
# Line 312 | Line 308 | public class TreeMap<K,V>
308          if (size==0 && mapSize!=0 && map instanceof SortedMap) {
309              Comparator c = ((SortedMap)map).comparator();
310              if (c == comparator || (c != null && c.equals(comparator))) {
311 <                ++modCount;
312 <                try {
313 <                    buildFromSorted(mapSize, map.entrySet().iterator(),
314 <                                    null, null);
315 <                } catch (java.io.IOException cannotHappen) {
316 <                } catch (ClassNotFoundException cannotHappen) {
317 <                }
318 <                return;
311 >                ++modCount;
312 >                try {
313 >                    buildFromSorted(mapSize, map.entrySet().iterator(),
314 >                                    null, null);
315 >                } catch (java.io.IOException cannotHappen) {
316 >                } catch (ClassNotFoundException cannotHappen) {
317 >                }
318 >                return;
319              }
320          }
321          super.putAll(map);
# Line 343 | Line 339 | public class TreeMap<K,V>
339              return getEntryUsingComparator(key);
340          if (key == null)
341              throw new NullPointerException();
342 <        Comparable<? super K> k = (Comparable<? super K>) key;
342 >        Comparable<? super K> k = (Comparable<? super K>) key;
343          Entry<K,V> p = root;
344          while (p != null) {
345              int cmp = k.compareTo(p.key);
# Line 361 | Line 357 | public class TreeMap<K,V>
357       * Version of getEntry using comparator. Split off from getEntry
358       * for performance. (This is not worth doing for most methods,
359       * that are less dependent on comparator performance, but is
360 <     * worthwhile for get and put.)
360 >     * worthwhile here.)
361       */
362      final Entry<K,V> getEntryUsingComparator(Object key) {
363 <        K k = (K) key;
363 >        K k = (K) key;
364          Comparator<? super K> cpr = comparator;
365 <        Entry<K,V> p = root;
366 <        while (p != null) {
367 <            int cmp = cpr.compare(k, p.key);
368 <            if (cmp < 0)
369 <                p = p.left;
370 <            else if (cmp > 0)
371 <                p = p.right;
372 <            else
373 <                return p;
365 >        if (cpr != null) {
366 >            Entry<K,V> p = root;
367 >            while (p != null) {
368 >                int cmp = cpr.compare(k, p.key);
369 >                if (cmp < 0)
370 >                    p = p.left;
371 >                else if (cmp > 0)
372 >                    p = p.right;
373 >                else
374 >                    return p;
375 >            }
376          }
377          return null;
378      }
# Line 509 | Line 507 | public class TreeMap<K,V>
507      }
508  
509      /**
512     * Returns the key corresponding to the specified Entry.
513     * @throws NoSuchElementException if the Entry is null
514     */
515    static <K> K key(Entry<K,?> e) {
516        if (e==null)
517            throw new NoSuchElementException();
518        return e.key;
519    }
520
521    /**
510       * Associates the specified value with the specified key in this map.
511       * If the map previously contained a mapping for the key, the old
512       * value is replaced.
# Line 537 | Line 525 | public class TreeMap<K,V>
525       *         does not permit null keys
526       */
527      public V put(K key, V value) {
540        // Offload comparator-based version for sake of performance
541        if (comparator != null)
542            return putUsingComparator(key, value);
543        if (key == null)
544            throw new NullPointerException();
545        Comparable<? super K> k = (Comparable<? super K>) key;
546
528          Entry<K,V> t = root;
529 <        while (t != null) {
530 <            int cmp = k.compareTo(t.key);
531 <            if (cmp == 0) {
532 <                return t.setValue(value);
533 <            } else if (cmp < 0) {
534 <                if (t.left != null) {
529 >        if (t == null) {
530 >            // TBD:
531 >            // 5045147: (coll) Adding null to an empty TreeSet should
532 >            // throw NullPointerException
533 >            //
534 >            // compare(key, key); // type check
535 >            root = new Entry<K,V>(key, value, null);
536 >            size = 1;
537 >            modCount++;
538 >            return null;
539 >        }
540 >        int cmp;
541 >        Entry<K,V> parent;
542 >        // split comparator and comparable paths
543 >        Comparator<? super K> cpr = comparator;
544 >        if (cpr != null) {
545 >            do {
546 >                parent = t;
547 >                cmp = cpr.compare(key, t.key);
548 >                if (cmp < 0)
549                      t = t.left;
550 <                } else {
556 <                    incrementSize();
557 <                    fixAfterInsertion(t.left = new Entry<K,V>(key, value, t));
558 <                    return null;
559 <                }
560 <            } else { // cmp > 0
561 <                if (t.right != null) {
550 >                else if (cmp > 0)
551                      t = t.right;
552 <                } else {
553 <                    incrementSize();
554 <                    fixAfterInsertion(t.right = new Entry<K,V>(key, value, t));
566 <                    return null;
567 <                }
568 <            }
552 >                else
553 >                    return t.setValue(value);
554 >            } while (t != null);
555          }
556 <        incrementSize();
557 <        root = new Entry<K,V>(key, value, null);
558 <        return null;
559 <    }
560 <
561 <    /**
562 <     * Version of put using comparator. Split off from put for
563 <     * performance.
578 <     */
579 <    final V putUsingComparator(K key, V value) {
580 <        Comparator<? super K> cpr = comparator;
581 <        Entry<K,V> t = root;
582 <        while (t != null) {
583 <            int cmp = cpr.compare(key, t.key);
584 <            if (cmp == 0) {
585 <                return t.setValue(value);
586 <            } else if (cmp < 0) {
587 <                if (t.left != null) {
556 >        else {
557 >            if (key == null)
558 >                throw new NullPointerException();
559 >            Comparable<? super K> k = (Comparable<? super K>) key;
560 >            do {
561 >                parent = t;
562 >                cmp = k.compareTo(t.key);
563 >                if (cmp < 0)
564                      t = t.left;
565 <                } else {
590 <                    incrementSize();
591 <                    fixAfterInsertion(t.left = new Entry<K,V>(key, value, t));
592 <                    return null;
593 <                }
594 <            } else { // cmp > 0
595 <                if (t.right != null) {
565 >                else if (cmp > 0)
566                      t = t.right;
567 <                } else {
568 <                    incrementSize();
569 <                    fixAfterInsertion(t.right = new Entry<K,V>(key, value, t));
600 <                    return null;
601 <                }
602 <            }
567 >                else
568 >                    return t.setValue(value);
569 >            } while (t != null);
570          }
571 <        cpr.compare(key, key); // type check
572 <        incrementSize();
573 <        root = new Entry<K,V>(key, value, null);
571 >        Entry<K,V> e = new Entry<K,V>(key, value, parent);
572 >        if (cmp < 0)
573 >            parent.left = e;
574 >        else
575 >            parent.right = e;
576 >        fixAfterInsertion(e);
577 >        size++;
578 >        modCount++;
579          return null;
580      }
581  
# Line 679 | Line 651 | public class TreeMap<K,V>
651       * @since 1.6
652       */
653      public Map.Entry<K,V> firstEntry() {
654 <        Entry<K,V> e = getFirstEntry();
683 <        return (e == null)? null : new AbstractMap.SimpleImmutableEntry<K,V>(e);
654 >        return exportEntry(getFirstEntry());
655      }
656  
657      /**
658       * @since 1.6
659       */
660      public Map.Entry<K,V> lastEntry() {
661 <        Entry<K,V> e = getLastEntry();
691 <        return (e == null)? null : new AbstractMap.SimpleImmutableEntry<K,V>(e);
661 >        return exportEntry(getLastEntry());
662      }
663  
664      /**
# Line 696 | Line 666 | public class TreeMap<K,V>
666       */
667      public Map.Entry<K,V> pollFirstEntry() {
668          Entry<K,V> p = getFirstEntry();
669 <        if (p == null)
670 <            return null;
671 <        Map.Entry<K,V> result = new AbstractMap.SimpleImmutableEntry<K,V>(p);
702 <        deleteEntry(p);
669 >        Map.Entry<K,V> result = exportEntry(p);
670 >        if (p != null)
671 >            deleteEntry(p);
672          return result;
673      }
674  
# Line 708 | Line 677 | public class TreeMap<K,V>
677       */
678      public Map.Entry<K,V> pollLastEntry() {
679          Entry<K,V> p = getLastEntry();
680 <        if (p == null)
681 <            return null;
682 <        Map.Entry<K,V> result = new AbstractMap.SimpleImmutableEntry<K,V>(p);
714 <        deleteEntry(p);
680 >        Map.Entry<K,V> result = exportEntry(p);
681 >        if (p != null)
682 >            deleteEntry(p);
683          return result;
684      }
685  
# Line 723 | Line 691 | public class TreeMap<K,V>
691       * @since 1.6
692       */
693      public Map.Entry<K,V> lowerEntry(K key) {
694 <        Entry<K,V> e =  getLowerEntry(key);
727 <        return (e == null)? null : new AbstractMap.SimpleImmutableEntry<K,V>(e);
694 >        return exportEntry(getLowerEntry(key));
695      }
696  
697      /**
# Line 735 | Line 702 | public class TreeMap<K,V>
702       * @since 1.6
703       */
704      public K lowerKey(K key) {
705 <        Entry<K,V> e =  getLowerEntry(key);
739 <        return (e == null)? null : e.key;
705 >        return keyOrNull(getLowerEntry(key));
706      }
707  
708      /**
# Line 747 | Line 713 | public class TreeMap<K,V>
713       * @since 1.6
714       */
715      public Map.Entry<K,V> floorEntry(K key) {
716 <        Entry<K,V> e = getFloorEntry(key);
751 <        return (e == null)? null : new AbstractMap.SimpleImmutableEntry<K,V>(e);
716 >        return exportEntry(getFloorEntry(key));
717      }
718  
719      /**
# Line 759 | Line 724 | public class TreeMap<K,V>
724       * @since 1.6
725       */
726      public K floorKey(K key) {
727 <        Entry<K,V> e = getFloorEntry(key);
763 <        return (e == null)? null : e.key;
727 >        return keyOrNull(getFloorEntry(key));
728      }
729  
730      /**
# Line 771 | Line 735 | public class TreeMap<K,V>
735       * @since 1.6
736       */
737      public Map.Entry<K,V> ceilingEntry(K key) {
738 <        Entry<K,V> e = getCeilingEntry(key);
775 <        return (e == null)? null : new AbstractMap.SimpleImmutableEntry<K,V>(e);
738 >        return exportEntry(getCeilingEntry(key));
739      }
740  
741      /**
# Line 783 | Line 746 | public class TreeMap<K,V>
746       * @since 1.6
747       */
748      public K ceilingKey(K key) {
749 <        Entry<K,V> e = getCeilingEntry(key);
787 <        return (e == null)? null : e.key;
749 >        return keyOrNull(getCeilingEntry(key));
750      }
751  
752      /**
# Line 795 | Line 757 | public class TreeMap<K,V>
757       * @since 1.6
758       */
759      public Map.Entry<K,V> higherEntry(K key) {
760 <        Entry<K,V> e = getHigherEntry(key);
799 <        return (e == null)? null : new AbstractMap.SimpleImmutableEntry<K,V>(e);
760 >        return exportEntry(getHigherEntry(key));
761      }
762  
763      /**
# Line 807 | Line 768 | public class TreeMap<K,V>
768       * @since 1.6
769       */
770      public K higherKey(K key) {
771 <        Entry<K,V> e = getHigherEntry(key);
811 <        return (e == null)? null : e.key;
771 >        return keyOrNull(getHigherEntry(key));
772      }
773  
774      // Views
# Line 994 | Line 954 | public class TreeMap<K,V>
954          }
955  
956          public boolean contains(Object o) {
957 <            for (Entry<K,V> e = getFirstEntry(); e != null; e = successor(e))
998 <                if (valEquals(e.getValue(), o))
999 <                    return true;
1000 <            return false;
957 >            return TreeMap.this.containsValue(o);
958          }
959  
960          public boolean remove(Object o) {
# Line 1064 | Line 1021 | public class TreeMap<K,V>
1021      }
1022  
1023      Iterator<K> descendingKeyIterator() {
1024 <        return new DescendingKeyIterator(getFirstEntry());
1024 >        return new DescendingKeyIterator(getLastEntry());
1025      }
1026  
1027      static final class KeySet<E> extends AbstractSet<E> implements NavigableSet<E> {
# Line 1110 | Line 1067 | public class TreeMap<K,V>
1067              return size() != oldSize;
1068          }
1069          public NavigableSet<E> subSet(E fromElement, boolean fromInclusive,
1070 <                                      E toElement, boolean toInclusive) {
1071 <            return new TreeSet<E>(m.subMap(fromElement, fromInclusive,
1072 <                                           toElement,   toInclusive));
1070 >                                      E toElement,   boolean toInclusive) {
1071 >            return new KeySet<E>(m.subMap(fromElement, fromInclusive,
1072 >                                          toElement,   toInclusive));
1073          }
1074          public NavigableSet<E> headSet(E toElement, boolean inclusive) {
1075 <            return new TreeSet<E>(m.headMap(toElement, inclusive));
1075 >            return new KeySet<E>(m.headMap(toElement, inclusive));
1076          }
1077          public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
1078 <            return new TreeSet<E>(m.tailMap(fromElement, inclusive));
1078 >            return new KeySet<E>(m.tailMap(fromElement, inclusive));
1079          }
1080          public SortedSet<E> subSet(E fromElement, E toElement) {
1081              return subSet(fromElement, true, toElement, false);
# Line 1130 | Line 1087 | public class TreeMap<K,V>
1087              return tailSet(fromElement, true);
1088          }
1089          public NavigableSet<E> descendingSet() {
1090 <            return new TreeSet(m.descendingMap());
1090 >            return new KeySet(m.descendingMap());
1091          }
1092      }
1093  
# Line 1152 | Line 1109 | public class TreeMap<K,V>
1109              return next != null;
1110          }
1111  
1112 <        final Entry<K,V> nextEntry() {
1113 <            Entry<K,V> e = lastReturned = next;
1112 >        final Entry<K,V> nextEntry() {
1113 >            Entry<K,V> e = next;
1114              if (e == null)
1115                  throw new NoSuchElementException();
1116              if (modCount != expectedModCount)
1117                  throw new ConcurrentModificationException();
1118              next = successor(e);
1119 +            lastReturned = e;
1120              return e;
1121          }
1122  
1123          final Entry<K,V> prevEntry() {
1124 <            Entry<K,V> e = lastReturned= next;
1124 >            Entry<K,V> e = next;
1125              if (e == null)
1126                  throw new NoSuchElementException();
1127              if (modCount != expectedModCount)
1128                  throw new ConcurrentModificationException();
1129              next = predecessor(e);
1130 +            lastReturned = e;
1131              return e;
1132          }
1133  
# Line 1177 | Line 1136 | public class TreeMap<K,V>
1136                  throw new IllegalStateException();
1137              if (modCount != expectedModCount)
1138                  throw new ConcurrentModificationException();
1139 +            // deleted entries are replaced by their successors
1140              if (lastReturned.left != null && lastReturned.right != null)
1141                  next = lastReturned;
1142              deleteEntry(lastReturned);
1143 <            expectedModCount++;
1143 >            expectedModCount = modCount;
1144              lastReturned = null;
1145          }
1146      }
# Line 1221 | Line 1181 | public class TreeMap<K,V>
1181          }
1182      }
1183  
1184 +    // Little utilities
1185 +
1186 +    /**
1187 +     * Compares two keys using the correct comparison method for this TreeMap.
1188 +     */
1189 +    final int compare(Object k1, Object k2) {
1190 +        return comparator==null ? ((Comparable<? super K>)k1).compareTo((K)k2)
1191 +            : comparator.compare((K)k1, (K)k2);
1192 +    }
1193 +
1194 +    /**
1195 +     * Test two values for equality.  Differs from o1.equals(o2) only in
1196 +     * that it copes with <tt>null</tt> o1 properly.
1197 +     */
1198 +    static final boolean valEquals(Object o1, Object o2) {
1199 +        return (o1==null ? o2==null : o1.equals(o2));
1200 +    }
1201 +
1202 +    /**
1203 +     * Return SimpleImmutableEntry for entry, or null if null
1204 +     */
1205 +    static <K,V> Map.Entry<K,V> exportEntry(TreeMap.Entry<K,V> e) {
1206 +        return e == null? null :
1207 +            new AbstractMap.SimpleImmutableEntry<K,V>(e);
1208 +    }
1209 +
1210 +    /**
1211 +     * Return key for entry, or null if null
1212 +     */
1213 +    static <K,V> K keyOrNull(TreeMap.Entry<K,V> e) {
1214 +        return e == null? null : e.key;
1215 +    }
1216 +
1217 +    /**
1218 +     * Returns the key corresponding to the specified Entry.
1219 +     * @throws NoSuchElementException if the Entry is null
1220 +     */
1221 +    static <K> K key(Entry<K,?> e) {
1222 +        if (e==null)
1223 +            throw new NoSuchElementException();
1224 +        return e.key;
1225 +    }
1226 +
1227 +
1228      // SubMaps
1229  
1230 <    static abstract class NavigableSubMap<K,V> extends AbstractMap<K,V>
1230 >    /**
1231 >     * Dummy value serving as unmatchable fence key for unbounded
1232 >     * SubMapIterators
1233 >     */
1234 >    private static final Object UNBOUNDED = new Object();
1235 >
1236 >    /**
1237 >     * @serial include
1238 >     */
1239 >    abstract static class NavigableSubMap<K,V> extends AbstractMap<K,V>
1240          implements NavigableMap<K,V>, java.io.Serializable {
1241 <        /*
1241 >        /**
1242           * The backing map.
1243           */
1244          final TreeMap<K,V> m;
1245  
1246 <        /*
1246 >        /**
1247           * Endpoints are represented as triples (fromStart, lo,
1248           * loInclusive) and (toEnd, hi, hiInclusive). If fromStart is
1249           * true, then the low (absolute) bound is the start of the
# Line 1238 | Line 1251 | public class TreeMap<K,V>
1251           * if loInclusive is true, lo is the inclusive bound, else lo
1252           * is the exclusive bound. Similarly for the upper bound.
1253           */
1241
1254          final K lo, hi;
1255          final boolean fromStart, toEnd;
1256          final boolean loInclusive, hiInclusive;
# Line 1298 | Line 1310 | public class TreeMap<K,V>
1310              return inclusive ? inRange(key) : inClosedRange(key);
1311          }
1312  
1301        /**
1302         * Return SimpleImmutableEntry for entry, or null if null
1303         */
1304        static <K,V> Map.Entry<K,V> exportEntry(TreeMap.Entry<K,V> e) {
1305            return e == null? null :
1306                new AbstractMap.SimpleImmutableEntry<K,V>(e);
1307        }
1308
1309        /**
1310         * Return key for entry, or null if null
1311         */
1312        static <K,V> K exportKey(TreeMap.Entry<K,V> e) {
1313            return e == null? null : e.key;
1314        }
1315
1313          /*
1314           * Absolute versions of relation operations.
1315           * Subclasses map to these using like-named "sub"
# Line 1320 | Line 1317 | public class TreeMap<K,V>
1317           */
1318  
1319          final TreeMap.Entry<K,V> absLowest() {
1320 <            TreeMap.Entry<K,V> e =
1320 >            TreeMap.Entry<K,V> e =
1321                  (fromStart ?  m.getFirstEntry() :
1322                   (loInclusive ? m.getCeilingEntry(lo) :
1323                                  m.getHigherEntry(lo)));
# Line 1328 | Line 1325 | public class TreeMap<K,V>
1325          }
1326  
1327          final TreeMap.Entry<K,V> absHighest() {
1328 <            TreeMap.Entry<K,V> e =
1328 >            TreeMap.Entry<K,V> e =
1329                  (toEnd ?  m.getLastEntry() :
1330                   (hiInclusive ?  m.getFloorEntry(hi) :
1331                                   m.getLowerEntry(hi)));
1332              return (e == null || tooLow(e.key)) ? null : e;
1333          }
1334 <        
1334 >
1335          final TreeMap.Entry<K,V> absCeiling(K key) {
1336              if (tooLow(key))
1337                  return absLowest();
1338 <            TreeMap.Entry<K,V> e = m.getCeilingEntry(key);
1338 >            TreeMap.Entry<K,V> e = m.getCeilingEntry(key);
1339              return (e == null || tooHigh(e.key)) ? null : e;
1340          }
1341  
1342          final TreeMap.Entry<K,V> absHigher(K key) {
1343              if (tooLow(key))
1344                  return absLowest();
1345 <            TreeMap.Entry<K,V> e = m.getHigherEntry(key);
1345 >            TreeMap.Entry<K,V> e = m.getHigherEntry(key);
1346              return (e == null || tooHigh(e.key)) ? null : e;
1347          }
1348  
1349          final TreeMap.Entry<K,V> absFloor(K key) {
1350              if (tooHigh(key))
1351                  return absHighest();
1352 <            TreeMap.Entry<K,V> e = m.getFloorEntry(key);
1352 >            TreeMap.Entry<K,V> e = m.getFloorEntry(key);
1353              return (e == null || tooLow(e.key)) ? null : e;
1354          }
1355  
1356          final TreeMap.Entry<K,V> absLower(K key) {
1357              if (tooHigh(key))
1358                  return absHighest();
1359 <            TreeMap.Entry<K,V> e = m.getLowerEntry(key);
1359 >            TreeMap.Entry<K,V> e = m.getLowerEntry(key);
1360              return (e == null || tooLow(e.key)) ? null : e;
1361          }
1362  
1363          /** Returns the absolute high fence for ascending traversal */
1364          final TreeMap.Entry<K,V> absHighFence() {
1365 <            return (toEnd ? null : (hiInclusive ?
1365 >            return (toEnd ? null : (hiInclusive ?
1366                                      m.getHigherEntry(hi) :
1367                                      m.getCeilingEntry(hi)));
1368          }
# Line 1378 | Line 1375 | public class TreeMap<K,V>
1375          }
1376  
1377          // Abstract methods defined in ascending vs descending classes
1378 <        // These relay to the appropriate  absolute versions
1378 >        // These relay to the appropriate absolute versions
1379  
1380          abstract TreeMap.Entry<K,V> subLowest();
1381          abstract TreeMap.Entry<K,V> subHighest();
# Line 1426 | Line 1423 | public class TreeMap<K,V>
1423          }
1424  
1425          public final K ceilingKey(K key) {
1426 <            return exportKey(subCeiling(key));
1426 >            return keyOrNull(subCeiling(key));
1427          }
1428  
1429          public final Map.Entry<K,V> higherEntry(K key) {
# Line 1434 | Line 1431 | public class TreeMap<K,V>
1431          }
1432  
1433          public final K higherKey(K key) {
1434 <            return exportKey(subHigher(key));
1434 >            return keyOrNull(subHigher(key));
1435          }
1436  
1437          public final Map.Entry<K,V> floorEntry(K key) {
# Line 1442 | Line 1439 | public class TreeMap<K,V>
1439          }
1440  
1441          public final K floorKey(K key) {
1442 <            return exportKey(subFloor(key));
1442 >            return keyOrNull(subFloor(key));
1443          }
1444  
1445          public final Map.Entry<K,V> lowerEntry(K key) {
# Line 1450 | Line 1447 | public class TreeMap<K,V>
1447          }
1448  
1449          public final K lowerKey(K key) {
1450 <            return exportKey(subLower(key));
1450 >            return keyOrNull(subLower(key));
1451          }
1452  
1453          public final K firstKey() {
# Line 1470 | Line 1467 | public class TreeMap<K,V>
1467          }
1468  
1469          public final Map.Entry<K,V> pollFirstEntry() {
1470 <            TreeMap.Entry<K,V> e = subLowest();
1470 >            TreeMap.Entry<K,V> e = subLowest();
1471              Map.Entry<K,V> result = exportEntry(e);
1472              if (e != null)
1473                  m.deleteEntry(e);
# Line 1478 | Line 1475 | public class TreeMap<K,V>
1475          }
1476  
1477          public final Map.Entry<K,V> pollLastEntry() {
1478 <            TreeMap.Entry<K,V> e = subHighest();
1478 >            TreeMap.Entry<K,V> e = subHighest();
1479              Map.Entry<K,V> result = exportEntry(e);
1480              if (e != null)
1481                  m.deleteEntry(e);
# Line 1575 | Line 1572 | public class TreeMap<K,V>
1572          abstract class SubMapIterator<T> implements Iterator<T> {
1573              TreeMap.Entry<K,V> lastReturned;
1574              TreeMap.Entry<K,V> next;
1575 <            final K fenceKey;
1575 >            final Object fenceKey;
1576              int expectedModCount;
1577  
1578              SubMapIterator(TreeMap.Entry<K,V> first,
# Line 1583 | Line 1580 | public class TreeMap<K,V>
1580                  expectedModCount = m.modCount;
1581                  lastReturned = null;
1582                  next = first;
1583 <                fenceKey = fence == null ? null : fence.key;
1583 >                fenceKey = fence == null ? UNBOUNDED : fence.key;
1584              }
1585  
1586              public final boolean hasNext() {
# Line 1591 | Line 1588 | public class TreeMap<K,V>
1588              }
1589  
1590              final TreeMap.Entry<K,V> nextEntry() {
1591 <                TreeMap.Entry<K,V> e = lastReturned = next;
1591 >                TreeMap.Entry<K,V> e = next;
1592                  if (e == null || e.key == fenceKey)
1593                      throw new NoSuchElementException();
1594                  if (m.modCount != expectedModCount)
1595                      throw new ConcurrentModificationException();
1596                  next = successor(e);
1597 +                lastReturned = e;
1598                  return e;
1599              }
1600  
1601              final TreeMap.Entry<K,V> prevEntry() {
1602 <                TreeMap.Entry<K,V> e = lastReturned = next;
1602 >                TreeMap.Entry<K,V> e = next;
1603                  if (e == null || e.key == fenceKey)
1604                      throw new NoSuchElementException();
1605                  if (m.modCount != expectedModCount)
1606                      throw new ConcurrentModificationException();
1607                  next = predecessor(e);
1608 +                lastReturned = e;
1609                  return e;
1610              }
1611  
1612 <            public void remove() {
1612 >            final void removeAscending() {
1613                  if (lastReturned == null)
1614                      throw new IllegalStateException();
1615                  if (m.modCount != expectedModCount)
1616                      throw new ConcurrentModificationException();
1617 +                // deleted entries are replaced by their successors
1618                  if (lastReturned.left != null && lastReturned.right != null)
1619                      next = lastReturned;
1620                  m.deleteEntry(lastReturned);
1621                expectedModCount++;
1621                  lastReturned = null;
1622 +                expectedModCount = m.modCount;
1623 +            }
1624 +
1625 +            final void removeDescending() {
1626 +                if (lastReturned == null)
1627 +                    throw new IllegalStateException();
1628 +                if (m.modCount != expectedModCount)
1629 +                    throw new ConcurrentModificationException();
1630 +                m.deleteEntry(lastReturned);
1631 +                lastReturned = null;
1632 +                expectedModCount = m.modCount;
1633              }
1634 +
1635          }
1636  
1637          final class SubMapEntryIterator extends SubMapIterator<Map.Entry<K,V>> {
# Line 1631 | Line 1642 | public class TreeMap<K,V>
1642              public Map.Entry<K,V> next() {
1643                  return nextEntry();
1644              }
1645 +            public void remove() {
1646 +                removeAscending();
1647 +            }
1648          }
1649  
1650          final class SubMapKeyIterator extends SubMapIterator<K> {
# Line 1641 | Line 1655 | public class TreeMap<K,V>
1655              public K next() {
1656                  return nextEntry().key;
1657              }
1658 +            public void remove() {
1659 +                removeAscending();
1660 +            }
1661          }
1662  
1663          final class DescendingSubMapEntryIterator extends SubMapIterator<Map.Entry<K,V>> {
# Line 1652 | Line 1669 | public class TreeMap<K,V>
1669              public Map.Entry<K,V> next() {
1670                  return prevEntry();
1671              }
1672 +            public void remove() {
1673 +                removeDescending();
1674 +            }
1675          }
1676  
1677          final class DescendingSubMapKeyIterator extends SubMapIterator<K> {
# Line 1662 | Line 1682 | public class TreeMap<K,V>
1682              public K next() {
1683                  return prevEntry().key;
1684              }
1685 +            public void remove() {
1686 +                removeDescending();
1687 +            }
1688          }
1689      }
1690  
1691 +    /**
1692 +     * @serial include
1693 +     */
1694      static final class AscendingSubMap<K,V> extends NavigableSubMap<K,V> {
1695          private static final long serialVersionUID = 912986545866124060L;
1696  
1697          AscendingSubMap(TreeMap<K,V> m,
1698                          boolean fromStart, K lo, boolean loInclusive,
1699 <                        boolean toEnd, K hi, boolean hiInclusive) {
1699 >                        boolean toEnd,     K hi, boolean hiInclusive) {
1700              super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive);
1701          }
1702  
# Line 1679 | Line 1705 | public class TreeMap<K,V>
1705          }
1706  
1707          public NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive,
1708 <                                        K toKey, boolean toInclusive) {
1708 >                                        K toKey,   boolean toInclusive) {
1709              if (!inRange(fromKey, fromInclusive))
1710                  throw new IllegalArgumentException("fromKey out of range");
1711              if (!inRange(toKey, toInclusive))
# Line 1690 | Line 1716 | public class TreeMap<K,V>
1716          }
1717  
1718          public NavigableMap<K,V> headMap(K toKey, boolean inclusive) {
1719 <            if (!inClosedRange(toKey))
1719 >            if (!inRange(toKey, inclusive))
1720                  throw new IllegalArgumentException("toKey out of range");
1721              return new AscendingSubMap(m,
1722                                         fromStart, lo,    loInclusive,
# Line 1741 | Line 1767 | public class TreeMap<K,V>
1767          TreeMap.Entry<K,V> subLower(K key)   { return absLower(key); }
1768      }
1769  
1770 +    /**
1771 +     * @serial include
1772 +     */
1773      static final class DescendingSubMap<K,V>  extends NavigableSubMap<K,V> {
1774          private static final long serialVersionUID = 912986545866120460L;
1775          DescendingSubMap(TreeMap<K,V> m,
1776                          boolean fromStart, K lo, boolean loInclusive,
1777 <                        boolean toEnd, K hi, boolean hiInclusive) {
1777 >                        boolean toEnd,     K hi, boolean hiInclusive) {
1778              super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive);
1779          }
1780  
# Line 1757 | Line 1786 | public class TreeMap<K,V>
1786          }
1787  
1788          public NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive,
1789 <                                        K toKey, boolean toInclusive) {
1789 >                                        K toKey,   boolean toInclusive) {
1790              if (!inRange(fromKey, fromInclusive))
1791                  throw new IllegalArgumentException("fromKey out of range");
1792              if (!inRange(toKey, toInclusive))
# Line 1820 | Line 1849 | public class TreeMap<K,V>
1849      }
1850  
1851      /**
1823     * Compares two keys using the correct comparison method for this TreeMap.
1824     */
1825    final int compare(Object k1, Object k2) {
1826        return comparator==null ? ((Comparable<? super K>)k1).compareTo((K)k2)
1827            : comparator.compare((K)k1, (K)k2);
1828    }
1829
1830    /**
1831     * Test two values for equality.  Differs from o1.equals(o2) only in
1832     * that it copes with <tt>null</tt> o1 properly.
1833     */
1834    final static boolean valEquals(Object o1, Object o2) {
1835        return (o1==null ? o2==null : o1.equals(o2));
1836    }
1837
1838    /**
1852       * This class exists solely for the sake of serialization
1853       * compatibility with previous releases of TreeMap that did not
1854       * support NavigableMap.  It translates an old-version SubMap into
1855       * a new-version AscendingSubMap. This class is never otherwise
1856       * used.
1857 +     *
1858 +     * @serial include
1859       */
1860      private class SubMap extends AbstractMap<K,V>
1861 <        implements SortedMap<K,V>, java.io.Serializable {
1861 >        implements SortedMap<K,V>, java.io.Serializable {
1862          private static final long serialVersionUID = -6520786458950516097L;
1863          private boolean fromStart = false, toEnd = false;
1864          private K fromKey, toKey;
# Line 1862 | Line 1877 | public class TreeMap<K,V>
1877      }
1878  
1879  
1880 +    // Red-black mechanics
1881 +
1882      private static final boolean RED   = false;
1883      private static final boolean BLACK = true;
1884  
# Line 1871 | Line 1888 | public class TreeMap<K,V>
1888       */
1889  
1890      static final class Entry<K,V> implements Map.Entry<K,V> {
1891 <        K key;
1891 >        K key;
1892          V value;
1893          Entry<K,V> left = null;
1894          Entry<K,V> right = null;
# Line 1922 | Line 1939 | public class TreeMap<K,V>
1939          public boolean equals(Object o) {
1940              if (!(o instanceof Map.Entry))
1941                  return false;
1942 <            Map.Entry e = (Map.Entry)o;
1942 >            Map.Entry<?,?> e = (Map.Entry<?,?>)o;
1943  
1944              return valEquals(key,e.getKey()) && valEquals(value,e.getValue());
1945          }
# Line 2026 | Line 2043 | public class TreeMap<K,V>
2043  
2044      private static <K,V> void setColor(Entry<K,V> p, boolean c) {
2045          if (p != null)
2046 <            p.color = c;
2046 >            p.color = c;
2047      }
2048  
2049      private static <K,V> Entry<K,V> leftOf(Entry<K,V> p) {
# Line 2037 | Line 2054 | public class TreeMap<K,V>
2054          return (p == null) ? null: p.right;
2055      }
2056  
2057 <    /** From CLR **/
2057 >    /** From CLR */
2058      private void rotateLeft(Entry<K,V> p) {
2059 <        Entry<K,V> r = p.right;
2060 <        p.right = r.left;
2061 <        if (r.left != null)
2062 <            r.left.parent = p;
2063 <        r.parent = p.parent;
2064 <        if (p.parent == null)
2065 <            root = r;
2066 <        else if (p.parent.left == p)
2067 <            p.parent.left = r;
2068 <        else
2069 <            p.parent.right = r;
2070 <        r.left = p;
2071 <        p.parent = r;
2059 >        if (p != null) {
2060 >            Entry<K,V> r = p.right;
2061 >            p.right = r.left;
2062 >            if (r.left != null)
2063 >                r.left.parent = p;
2064 >            r.parent = p.parent;
2065 >            if (p.parent == null)
2066 >                root = r;
2067 >            else if (p.parent.left == p)
2068 >                p.parent.left = r;
2069 >            else
2070 >                p.parent.right = r;
2071 >            r.left = p;
2072 >            p.parent = r;
2073 >        }
2074      }
2075  
2076 <    /** From CLR **/
2076 >    /** From CLR */
2077      private void rotateRight(Entry<K,V> p) {
2078 <        Entry<K,V> l = p.left;
2079 <        p.left = l.right;
2080 <        if (l.right != null) l.right.parent = p;
2081 <        l.parent = p.parent;
2082 <        if (p.parent == null)
2083 <            root = l;
2084 <        else if (p.parent.right == p)
2085 <            p.parent.right = l;
2086 <        else p.parent.left = l;
2087 <        l.right = p;
2088 <        p.parent = l;
2078 >        if (p != null) {
2079 >            Entry<K,V> l = p.left;
2080 >            p.left = l.right;
2081 >            if (l.right != null) l.right.parent = p;
2082 >            l.parent = p.parent;
2083 >            if (p.parent == null)
2084 >                root = l;
2085 >            else if (p.parent.right == p)
2086 >                p.parent.right = l;
2087 >            else p.parent.left = l;
2088 >            l.right = p;
2089 >            p.parent = l;
2090 >        }
2091      }
2092  
2093 <
2073 <    /** From CLR **/
2093 >    /** From CLR */
2094      private void fixAfterInsertion(Entry<K,V> x) {
2095          x.color = RED;
2096  
# Line 2089 | Line 2109 | public class TreeMap<K,V>
2109                      }
2110                      setColor(parentOf(x), BLACK);
2111                      setColor(parentOf(parentOf(x)), RED);
2112 <                    if (parentOf(parentOf(x)) != null)
2093 <                        rotateRight(parentOf(parentOf(x)));
2112 >                    rotateRight(parentOf(parentOf(x)));
2113                  }
2114              } else {
2115                  Entry<K,V> y = leftOf(parentOf(parentOf(x)));
# Line 2106 | Line 2125 | public class TreeMap<K,V>
2125                      }
2126                      setColor(parentOf(x), BLACK);
2127                      setColor(parentOf(parentOf(x)), RED);
2128 <                    if (parentOf(parentOf(x)) != null)
2110 <                        rotateLeft(parentOf(parentOf(x)));
2128 >                    rotateLeft(parentOf(parentOf(x)));
2129                  }
2130              }
2131          }
# Line 2117 | Line 2135 | public class TreeMap<K,V>
2135      /**
2136       * Delete node p, and then rebalance the tree.
2137       */
2120
2138      private void deleteEntry(Entry<K,V> p) {
2139 <        decrementSize();
2139 >        modCount++;
2140 >        size--;
2141  
2142          // If strictly internal, copy successor's element to p and then make p
2143          // point to successor.
2144          if (p.left != null && p.right != null) {
2145 <            Entry<K,V> s = successor (p);
2145 >            Entry<K,V> s = successor(p);
2146              p.key = s.key;
2147              p.value = s.value;
2148              p = s;
# Line 2165 | Line 2183 | public class TreeMap<K,V>
2183          }
2184      }
2185  
2186 <    /** From CLR **/
2186 >    /** From CLR */
2187      private void fixAfterDeletion(Entry<K,V> x) {
2188          while (x != root && colorOf(x) == BLACK) {
2189              if (x == leftOf(parentOf(x))) {
# Line 2273 | Line 2291 | public class TreeMap<K,V>
2291          buildFromSorted(size, null, s, null);
2292      }
2293  
2294 <    /** Intended to be called only from TreeSet.readObject **/
2294 >    /** Intended to be called only from TreeSet.readObject */
2295      void readTreeSet(int size, java.io.ObjectInputStream s, V defaultVal)
2296          throws java.io.IOException, ClassNotFoundException {
2297          buildFromSorted(size, null, s, defaultVal);
2298      }
2299  
2300 <    /** Intended to be called only from TreeSet.addAll **/
2300 >    /** Intended to be called only from TreeSet.addAll */
2301      void addAllForTreeSet(SortedSet<? extends K> set, V defaultVal) {
2302 <        try {
2303 <            buildFromSorted(set.size(), set.iterator(), null, defaultVal);
2304 <        } catch (java.io.IOException cannotHappen) {
2305 <        } catch (ClassNotFoundException cannotHappen) {
2306 <        }
2302 >        try {
2303 >            buildFromSorted(set.size(), set.iterator(), null, defaultVal);
2304 >        } catch (java.io.IOException cannotHappen) {
2305 >        } catch (ClassNotFoundException cannotHappen) {
2306 >        }
2307      }
2308  
2309  
# Line 2320 | Line 2338 | public class TreeMap<K,V>
2338       *         This cannot occur if str is null.
2339       */
2340      private void buildFromSorted(int size, Iterator it,
2341 <                                 java.io.ObjectInputStream str,
2342 <                                 V defaultVal)
2341 >                                 java.io.ObjectInputStream str,
2342 >                                 V defaultVal)
2343          throws  java.io.IOException, ClassNotFoundException {
2344          this.size = size;
2345          root = buildFromSorted(0, 0, size-1, computeRedLevel(size),
2346 <                               it, str, defaultVal);
2346 >                               it, str, defaultVal);
2347      }
2348  
2349      /**
# Line 2343 | Line 2361 | public class TreeMap<K,V>
2361       *        Must be equal to computeRedLevel for tree of this size.
2362       */
2363      private final Entry<K,V> buildFromSorted(int level, int lo, int hi,
2364 <                                             int redLevel,
2365 <                                             Iterator it,
2366 <                                             java.io.ObjectInputStream str,
2367 <                                             V defaultVal)
2364 >                                             int redLevel,
2365 >                                             Iterator it,
2366 >                                             java.io.ObjectInputStream str,
2367 >                                             V defaultVal)
2368          throws  java.io.IOException, ClassNotFoundException {
2369          /*
2370           * Strategy: The root is the middlemost element. To get to it, we
# Line 2362 | Line 2380 | public class TreeMap<K,V>
2380  
2381          if (hi < lo) return null;
2382  
2383 <        int mid = (lo + hi) / 2;
2383 >        int mid = (lo + hi) >>> 1;
2384  
2385          Entry<K,V> left  = null;
2386          if (lo < mid)
2387              left = buildFromSorted(level+1, lo, mid - 1, redLevel,
2388 <                                   it, str, defaultVal);
2388 >                                   it, str, defaultVal);
2389  
2390          // extract key and/or value from iterator or stream
2391          K key;
# Line 2399 | Line 2417 | public class TreeMap<K,V>
2417  
2418          if (mid < hi) {
2419              Entry<K,V> right = buildFromSorted(level+1, mid+1, hi, redLevel,
2420 <                                               it, str, defaultVal);
2420 >                                               it, str, defaultVal);
2421              middle.right = right;
2422              right.parent = middle;
2423          }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines