--- jsr166/src/main/java/util/TreeMap.java 2006/04/23 20:59:49 1.34
+++ jsr166/src/main/java/util/TreeMap.java 2007/05/20 07:54:01 1.43
@@ -1,8 +1,26 @@
/*
- * %W% %E%
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
*/
package java.util;
@@ -68,7 +86,7 @@ package java.util;
* associated map using put.)
*
*
This class is a member of the
- *
+ *
* Java Collections Framework.
*
* @param the type of keys maintained by this map
@@ -510,7 +528,11 @@ public class TreeMap
public V put(K key, V value) {
Entry t = root;
if (t == null) {
- compare(key, key); // type check
+ // TBD:
+ // 5045147: (coll) Adding null to an empty TreeSet should
+ // throw NullPointerException
+ //
+ // compare(key, key); // type check
root = new Entry(key, value, null);
size = 1;
modCount++;
@@ -1046,7 +1068,7 @@ public class TreeMap
return size() != oldSize;
}
public NavigableSet subSet(E fromElement, boolean fromInclusive,
- E toElement, boolean toInclusive) {
+ E toElement, boolean toInclusive) {
return new TreeSet(m.subMap(fromElement, fromInclusive,
toElement, toInclusive));
}
@@ -1113,10 +1135,11 @@ public class TreeMap
throw new IllegalStateException();
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
+ // deleted entries are replaced by their successors
if (lastReturned.left != null && lastReturned.right != null)
next = lastReturned;
deleteEntry(lastReturned);
- expectedModCount++;
+ expectedModCount = modCount;
lastReturned = null;
}
}
@@ -1203,14 +1226,23 @@ public class TreeMap
// SubMaps
+ /**
+ * Dummy value serving as unmatchable fence key for unbounded
+ * SubMapIterators
+ */
+ private static final Object UNBOUNDED = new Object();
+
+ /**
+ * @serial include
+ */
static abstract class NavigableSubMap extends AbstractMap
implements NavigableMap, java.io.Serializable {
- /*
+ /**
* The backing map.
*/
final TreeMap m;
- /*
+ /**
* Endpoints are represented as triples (fromStart, lo,
* loInclusive) and (toEnd, hi, hiInclusive). If fromStart is
* true, then the low (absolute) bound is the start of the
@@ -1218,7 +1250,6 @@ public class TreeMap
* if loInclusive is true, lo is the inclusive bound, else lo
* is the exclusive bound. Similarly for the upper bound.
*/
-
final K lo, hi;
final boolean fromStart, toEnd;
final boolean loInclusive, hiInclusive;
@@ -1343,7 +1374,7 @@ public class TreeMap
}
// Abstract methods defined in ascending vs descending classes
- // These relay to the appropriate absolute versions
+ // These relay to the appropriate absolute versions
abstract TreeMap.Entry subLowest();
abstract TreeMap.Entry subHighest();
@@ -1540,7 +1571,7 @@ public class TreeMap
abstract class SubMapIterator implements Iterator {
TreeMap.Entry lastReturned;
TreeMap.Entry next;
- final K fenceKey;
+ final Object fenceKey;
int expectedModCount;
SubMapIterator(TreeMap.Entry first,
@@ -1548,7 +1579,7 @@ public class TreeMap
expectedModCount = m.modCount;
lastReturned = null;
next = first;
- fenceKey = fence == null ? null : fence.key;
+ fenceKey = fence == null ? UNBOUNDED : fence.key;
}
public final boolean hasNext() {
@@ -1575,17 +1606,29 @@ public class TreeMap
return e;
}
- public void remove() {
+ final void removeAscending() {
if (lastReturned == null)
throw new IllegalStateException();
if (m.modCount != expectedModCount)
throw new ConcurrentModificationException();
+ // deleted entries are replaced by their successors
if (lastReturned.left != null && lastReturned.right != null)
next = lastReturned;
m.deleteEntry(lastReturned);
- expectedModCount++;
lastReturned = null;
+ expectedModCount = m.modCount;
+ }
+
+ final void removeDescending() {
+ if (lastReturned == null)
+ throw new IllegalStateException();
+ if (m.modCount != expectedModCount)
+ throw new ConcurrentModificationException();
+ m.deleteEntry(lastReturned);
+ lastReturned = null;
+ expectedModCount = m.modCount;
}
+
}
final class SubMapEntryIterator extends SubMapIterator> {
@@ -1596,6 +1639,9 @@ public class TreeMap
public Map.Entry next() {
return nextEntry();
}
+ public void remove() {
+ removeAscending();
+ }
}
final class SubMapKeyIterator extends SubMapIterator {
@@ -1606,6 +1652,9 @@ public class TreeMap
public K next() {
return nextEntry().key;
}
+ public void remove() {
+ removeAscending();
+ }
}
final class DescendingSubMapEntryIterator extends SubMapIterator> {
@@ -1617,6 +1666,9 @@ public class TreeMap
public Map.Entry next() {
return prevEntry();
}
+ public void remove() {
+ removeDescending();
+ }
}
final class DescendingSubMapKeyIterator extends SubMapIterator {
@@ -1627,15 +1679,21 @@ public class TreeMap
public K next() {
return prevEntry().key;
}
+ public void remove() {
+ removeDescending();
+ }
}
}
+ /**
+ * @serial include
+ */
static final class AscendingSubMap extends NavigableSubMap {
private static final long serialVersionUID = 912986545866124060L;
AscendingSubMap(TreeMap m,
boolean fromStart, K lo, boolean loInclusive,
- boolean toEnd, K hi, boolean hiInclusive) {
+ boolean toEnd, K hi, boolean hiInclusive) {
super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive);
}
@@ -1644,7 +1702,7 @@ public class TreeMap
}
public NavigableMap subMap(K fromKey, boolean fromInclusive,
- K toKey, boolean toInclusive) {
+ K toKey, boolean toInclusive) {
if (!inRange(fromKey, fromInclusive))
throw new IllegalArgumentException("fromKey out of range");
if (!inRange(toKey, toInclusive))
@@ -1655,7 +1713,7 @@ public class TreeMap
}
public NavigableMap headMap(K toKey, boolean inclusive) {
- if (!inClosedRange(toKey))
+ if (!inRange(toKey, inclusive))
throw new IllegalArgumentException("toKey out of range");
return new AscendingSubMap(m,
fromStart, lo, loInclusive,
@@ -1706,11 +1764,14 @@ public class TreeMap
TreeMap.Entry subLower(K key) { return absLower(key); }
}
+ /**
+ * @serial include
+ */
static final class DescendingSubMap extends NavigableSubMap {
private static final long serialVersionUID = 912986545866120460L;
DescendingSubMap(TreeMap m,
boolean fromStart, K lo, boolean loInclusive,
- boolean toEnd, K hi, boolean hiInclusive) {
+ boolean toEnd, K hi, boolean hiInclusive) {
super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive);
}
@@ -1722,7 +1783,7 @@ public class TreeMap
}
public NavigableMap subMap(K fromKey, boolean fromInclusive,
- K toKey, boolean toInclusive) {
+ K toKey, boolean toInclusive) {
if (!inRange(fromKey, fromInclusive))
throw new IllegalArgumentException("fromKey out of range");
if (!inRange(toKey, toInclusive))
@@ -1790,6 +1851,8 @@ public class TreeMap
* support NavigableMap. It translates an old-version SubMap into
* a new-version AscendingSubMap. This class is never otherwise
* used.
+ *
+ * @serial include
*/
private class SubMap extends AbstractMap
implements SortedMap, java.io.Serializable {
@@ -1873,7 +1936,7 @@ public class TreeMap
public boolean equals(Object o) {
if (!(o instanceof Map.Entry))
return false;
- Map.Entry e = (Map.Entry)o;
+ Map.Entry,?> e = (Map.Entry,?>)o;
return valEquals(key,e.getKey()) && valEquals(value,e.getValue());
}
@@ -2314,7 +2377,7 @@ public class TreeMap
if (hi < lo) return null;
- int mid = (lo + hi) / 2;
+ int mid = (lo + hi) >>> 1;
Entry left = null;
if (lo < mid)