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.36 by jsr166, Tue May 9 16:35:40 2006 UTC vs.
Revision 1.52 by jsr166, Sat Oct 16 16:44:39 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 75 | Line 93 | package java.util;
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 219 | 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) {
# Line 291 | 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 322 | 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 343 | Line 360 | public class TreeMap<K,V>
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          if (cpr != null) {
366              Entry<K,V> p = root;
# Line 510 | Line 527 | public class TreeMap<K,V>
527      public V put(K key, V value) {
528          Entry<K,V> t = root;
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
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++;
# Line 1004 | 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 1051 | Line 1068 | public class TreeMap<K,V>
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));
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 1070 | 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 1092 | 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 1117 | 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 1175 | Line 1195 | public class TreeMap<K,V>
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 <    final static boolean valEquals(Object o1, Object o2) {
1198 >    static final boolean valEquals(Object o1, Object o2) {
1199          return (o1==null ? o2==null : o1.equals(o2));
1200      }
1201  
# Line 1208 | Line 1228 | public class TreeMap<K,V>
1228      // SubMaps
1229  
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 <    static abstract class NavigableSubMap<K,V> extends AbstractMap<K,V>
1239 >    abstract static class NavigableSubMap<K,V> extends AbstractMap<K,V>
1240          implements NavigableMap<K,V>, java.io.Serializable {
1241          /**
1242           * The backing map.
# Line 1291 | 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 1299 | 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)));
# Line 1309 | Line 1335 | public class TreeMap<K,V>
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  
# Line 1441 | 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 1449 | 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 1532 | Line 1558 | public class TreeMap<K,V>
1558                  if (!inRange(key))
1559                      return false;
1560                  TreeMap.Entry<K,V> node = m.getEntry(key);
1561 <                if (node!=null && valEquals(node.getValue(),entry.getValue())){
1561 >                if (node!=null && valEquals(node.getValue(),
1562 >                                            entry.getValue())) {
1563                      m.deleteEntry(node);
1564                      return true;
1565                  }
# Line 1546 | Line 1573 | public class TreeMap<K,V>
1573          abstract class SubMapIterator<T> implements Iterator<T> {
1574              TreeMap.Entry<K,V> lastReturned;
1575              TreeMap.Entry<K,V> next;
1576 <            final K fenceKey;
1576 >            final Object fenceKey;
1577              int expectedModCount;
1578  
1579              SubMapIterator(TreeMap.Entry<K,V> first,
# Line 1554 | Line 1581 | public class TreeMap<K,V>
1581                  expectedModCount = m.modCount;
1582                  lastReturned = null;
1583                  next = first;
1584 <                fenceKey = fence == null ? null : fence.key;
1584 >                fenceKey = fence == null ? UNBOUNDED : fence.key;
1585              }
1586  
1587              public final boolean hasNext() {
# Line 1562 | Line 1589 | public class TreeMap<K,V>
1589              }
1590  
1591              final TreeMap.Entry<K,V> nextEntry() {
1592 <                TreeMap.Entry<K,V> e = lastReturned = next;
1592 >                TreeMap.Entry<K,V> e = next;
1593                  if (e == null || e.key == fenceKey)
1594                      throw new NoSuchElementException();
1595                  if (m.modCount != expectedModCount)
1596                      throw new ConcurrentModificationException();
1597                  next = successor(e);
1598 +                lastReturned = e;
1599                  return e;
1600              }
1601  
1602              final TreeMap.Entry<K,V> prevEntry() {
1603 <                TreeMap.Entry<K,V> e = lastReturned = next;
1603 >                TreeMap.Entry<K,V> e = next;
1604                  if (e == null || e.key == fenceKey)
1605                      throw new NoSuchElementException();
1606                  if (m.modCount != expectedModCount)
1607                      throw new ConcurrentModificationException();
1608                  next = predecessor(e);
1609 +                lastReturned = e;
1610                  return e;
1611              }
1612  
1613 <            public void remove() {
1613 >            final void removeAscending() {
1614                  if (lastReturned == null)
1615                      throw new IllegalStateException();
1616                  if (m.modCount != expectedModCount)
1617                      throw new ConcurrentModificationException();
1618 +                // deleted entries are replaced by their successors
1619                  if (lastReturned.left != null && lastReturned.right != null)
1620                      next = lastReturned;
1621                  m.deleteEntry(lastReturned);
1592                expectedModCount++;
1622                  lastReturned = null;
1623 +                expectedModCount = m.modCount;
1624 +            }
1625 +
1626 +            final void removeDescending() {
1627 +                if (lastReturned == null)
1628 +                    throw new IllegalStateException();
1629 +                if (m.modCount != expectedModCount)
1630 +                    throw new ConcurrentModificationException();
1631 +                m.deleteEntry(lastReturned);
1632 +                lastReturned = null;
1633 +                expectedModCount = m.modCount;
1634              }
1635 +
1636          }
1637  
1638          final class SubMapEntryIterator extends SubMapIterator<Map.Entry<K,V>> {
# Line 1602 | Line 1643 | public class TreeMap<K,V>
1643              public Map.Entry<K,V> next() {
1644                  return nextEntry();
1645              }
1646 +            public void remove() {
1647 +                removeAscending();
1648 +            }
1649          }
1650  
1651          final class SubMapKeyIterator extends SubMapIterator<K> {
# Line 1612 | Line 1656 | public class TreeMap<K,V>
1656              public K next() {
1657                  return nextEntry().key;
1658              }
1659 +            public void remove() {
1660 +                removeAscending();
1661 +            }
1662          }
1663  
1664          final class DescendingSubMapEntryIterator extends SubMapIterator<Map.Entry<K,V>> {
# Line 1623 | Line 1670 | public class TreeMap<K,V>
1670              public Map.Entry<K,V> next() {
1671                  return prevEntry();
1672              }
1673 +            public void remove() {
1674 +                removeDescending();
1675 +            }
1676          }
1677  
1678          final class DescendingSubMapKeyIterator extends SubMapIterator<K> {
# Line 1633 | Line 1683 | public class TreeMap<K,V>
1683              public K next() {
1684                  return prevEntry().key;
1685              }
1686 +            public void remove() {
1687 +                removeDescending();
1688 +            }
1689          }
1690      }
1691  
# Line 1664 | Line 1717 | public class TreeMap<K,V>
1717          }
1718  
1719          public NavigableMap<K,V> headMap(K toKey, boolean inclusive) {
1720 <            if (!inClosedRange(toKey))
1720 >            if (!inRange(toKey, inclusive))
1721                  throw new IllegalArgumentException("toKey out of range");
1722              return new AscendingSubMap(m,
1723                                         fromStart, lo,    loInclusive,
1724                                         false,     toKey, inclusive);
1725          }
1726  
1727 <        public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive){
1727 >        public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) {
1728              if (!inRange(fromKey, inclusive))
1729                  throw new IllegalArgumentException("fromKey out of range");
1730              return new AscendingSubMap(m,
# Line 1752 | Line 1805 | public class TreeMap<K,V>
1805                                          toEnd, hi,    hiInclusive);
1806          }
1807  
1808 <        public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive){
1808 >        public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) {
1809              if (!inRange(fromKey, inclusive))
1810                  throw new IllegalArgumentException("fromKey out of range");
1811              return new DescendingSubMap(m,
# Line 1806 | Line 1859 | public class TreeMap<K,V>
1859       * @serial include
1860       */
1861      private class SubMap extends AbstractMap<K,V>
1862 <        implements SortedMap<K,V>, java.io.Serializable {
1862 >        implements SortedMap<K,V>, java.io.Serializable {
1863          private static final long serialVersionUID = -6520786458950516097L;
1864          private boolean fromStart = false, toEnd = false;
1865          private K fromKey, toKey;
# Line 1836 | Line 1889 | public class TreeMap<K,V>
1889       */
1890  
1891      static final class Entry<K,V> implements Map.Entry<K,V> {
1892 <        K key;
1892 >        K key;
1893          V value;
1894          Entry<K,V> left = null;
1895          Entry<K,V> right = null;
# Line 1991 | Line 2044 | public class TreeMap<K,V>
2044  
2045      private static <K,V> void setColor(Entry<K,V> p, boolean c) {
2046          if (p != null)
2047 <            p.color = c;
2047 >            p.color = c;
2048      }
2049  
2050      private static <K,V> Entry<K,V> leftOf(Entry<K,V> p) {
# Line 2090 | Line 2143 | public class TreeMap<K,V>
2143          // If strictly internal, copy successor's element to p and then make p
2144          // point to successor.
2145          if (p.left != null && p.right != null) {
2146 <            Entry<K,V> s = successor (p);
2146 >            Entry<K,V> s = successor(p);
2147              p.key = s.key;
2148              p.value = s.value;
2149              p = s;
# Line 2247 | Line 2300 | public class TreeMap<K,V>
2300  
2301      /** Intended to be called only from TreeSet.addAll */
2302      void addAllForTreeSet(SortedSet<? extends K> set, V defaultVal) {
2303 <        try {
2304 <            buildFromSorted(set.size(), set.iterator(), null, defaultVal);
2305 <        } catch (java.io.IOException cannotHappen) {
2306 <        } catch (ClassNotFoundException cannotHappen) {
2307 <        }
2303 >        try {
2304 >            buildFromSorted(set.size(), set.iterator(), null, defaultVal);
2305 >        } catch (java.io.IOException cannotHappen) {
2306 >        } catch (ClassNotFoundException cannotHappen) {
2307 >        }
2308      }
2309  
2310  
# Line 2286 | Line 2339 | public class TreeMap<K,V>
2339       *         This cannot occur if str is null.
2340       */
2341      private void buildFromSorted(int size, Iterator it,
2342 <                                 java.io.ObjectInputStream str,
2343 <                                 V defaultVal)
2342 >                                 java.io.ObjectInputStream str,
2343 >                                 V defaultVal)
2344          throws  java.io.IOException, ClassNotFoundException {
2345          this.size = size;
2346          root = buildFromSorted(0, 0, size-1, computeRedLevel(size),
2347 <                               it, str, defaultVal);
2347 >                               it, str, defaultVal);
2348      }
2349  
2350      /**
# Line 2309 | Line 2362 | public class TreeMap<K,V>
2362       *        Must be equal to computeRedLevel for tree of this size.
2363       */
2364      private final Entry<K,V> buildFromSorted(int level, int lo, int hi,
2365 <                                             int redLevel,
2366 <                                             Iterator it,
2367 <                                             java.io.ObjectInputStream str,
2368 <                                             V defaultVal)
2365 >                                             int redLevel,
2366 >                                             Iterator it,
2367 >                                             java.io.ObjectInputStream str,
2368 >                                             V defaultVal)
2369          throws  java.io.IOException, ClassNotFoundException {
2370          /*
2371           * Strategy: The root is the middlemost element. To get to it, we
# Line 2328 | Line 2381 | public class TreeMap<K,V>
2381  
2382          if (hi < lo) return null;
2383  
2384 <        int mid = (lo + hi) / 2;
2384 >        int mid = (lo + hi) >>> 1;
2385  
2386          Entry<K,V> left  = null;
2387          if (lo < mid)
2388              left = buildFromSorted(level+1, lo, mid - 1, redLevel,
2389 <                                   it, str, defaultVal);
2389 >                                   it, str, defaultVal);
2390  
2391          // extract key and/or value from iterator or stream
2392          K key;
# Line 2365 | Line 2418 | public class TreeMap<K,V>
2418  
2419          if (mid < hi) {
2420              Entry<K,V> right = buildFromSorted(level+1, mid+1, hi, redLevel,
2421 <                                               it, str, defaultVal);
2421 >                                               it, str, defaultVal);
2422              middle.right = right;
2423              right.parent = middle;
2424          }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines