1 |
|
/* |
2 |
|
* %W% %E% |
3 |
|
* |
4 |
< |
* Copyright 2006 Sun Microsystems, Inc. All rights reserved. |
4 |
> |
* Copyright 2007 Sun Microsystems, Inc. All rights reserved. |
5 |
|
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. |
6 |
|
*/ |
7 |
|
|
1117 |
|
throw new IllegalStateException(); |
1118 |
|
if (modCount != expectedModCount) |
1119 |
|
throw new ConcurrentModificationException(); |
1120 |
+ |
// deleted entries are replaced by their successors |
1121 |
|
if (lastReturned.left != null && lastReturned.right != null) |
1122 |
|
next = lastReturned; |
1123 |
|
deleteEntry(lastReturned); |
1124 |
< |
expectedModCount++; |
1124 |
> |
expectedModCount = modCount; |
1125 |
|
lastReturned = null; |
1126 |
|
} |
1127 |
|
} |
1209 |
|
// SubMaps |
1210 |
|
|
1211 |
|
/** |
1212 |
+ |
* Dummy value serving as unmatchable fence key for unbounded |
1213 |
+ |
* SubMapIterators |
1214 |
+ |
*/ |
1215 |
+ |
private static final Object UNBOUNDED = new Object(); |
1216 |
+ |
|
1217 |
+ |
/** |
1218 |
|
* @serial include |
1219 |
|
*/ |
1220 |
|
static abstract class NavigableSubMap<K,V> extends AbstractMap<K,V> |
1553 |
|
abstract class SubMapIterator<T> implements Iterator<T> { |
1554 |
|
TreeMap.Entry<K,V> lastReturned; |
1555 |
|
TreeMap.Entry<K,V> next; |
1556 |
< |
final K fenceKey; |
1556 |
> |
final Object fenceKey; |
1557 |
|
int expectedModCount; |
1558 |
|
|
1559 |
|
SubMapIterator(TreeMap.Entry<K,V> first, |
1561 |
|
expectedModCount = m.modCount; |
1562 |
|
lastReturned = null; |
1563 |
|
next = first; |
1564 |
< |
fenceKey = fence == null ? null : fence.key; |
1564 |
> |
fenceKey = fence == null ? UNBOUNDED : fence.key; |
1565 |
|
} |
1566 |
|
|
1567 |
|
public final boolean hasNext() { |
1588 |
|
return e; |
1589 |
|
} |
1590 |
|
|
1591 |
< |
public void remove() { |
1591 |
> |
final void removeAscending() { |
1592 |
|
if (lastReturned == null) |
1593 |
|
throw new IllegalStateException(); |
1594 |
|
if (m.modCount != expectedModCount) |
1595 |
|
throw new ConcurrentModificationException(); |
1596 |
+ |
// deleted entries are replaced by their successors |
1597 |
|
if (lastReturned.left != null && lastReturned.right != null) |
1598 |
|
next = lastReturned; |
1599 |
|
m.deleteEntry(lastReturned); |
1592 |
– |
expectedModCount++; |
1600 |
|
lastReturned = null; |
1601 |
+ |
expectedModCount = m.modCount; |
1602 |
|
} |
1603 |
+ |
|
1604 |
+ |
final void removeDescending() { |
1605 |
+ |
if (lastReturned == null) |
1606 |
+ |
throw new IllegalStateException(); |
1607 |
+ |
if (m.modCount != expectedModCount) |
1608 |
+ |
throw new ConcurrentModificationException(); |
1609 |
+ |
m.deleteEntry(lastReturned); |
1610 |
+ |
lastReturned = null; |
1611 |
+ |
expectedModCount = m.modCount; |
1612 |
+ |
} |
1613 |
+ |
|
1614 |
|
} |
1615 |
|
|
1616 |
|
final class SubMapEntryIterator extends SubMapIterator<Map.Entry<K,V>> { |
1621 |
|
public Map.Entry<K,V> next() { |
1622 |
|
return nextEntry(); |
1623 |
|
} |
1624 |
+ |
public void remove() { |
1625 |
+ |
removeAscending(); |
1626 |
+ |
} |
1627 |
|
} |
1628 |
|
|
1629 |
|
final class SubMapKeyIterator extends SubMapIterator<K> { |
1634 |
|
public K next() { |
1635 |
|
return nextEntry().key; |
1636 |
|
} |
1637 |
+ |
public void remove() { |
1638 |
+ |
removeAscending(); |
1639 |
+ |
} |
1640 |
|
} |
1641 |
|
|
1642 |
|
final class DescendingSubMapEntryIterator extends SubMapIterator<Map.Entry<K,V>> { |
1648 |
|
public Map.Entry<K,V> next() { |
1649 |
|
return prevEntry(); |
1650 |
|
} |
1651 |
+ |
public void remove() { |
1652 |
+ |
removeDescending(); |
1653 |
+ |
} |
1654 |
|
} |
1655 |
|
|
1656 |
|
final class DescendingSubMapKeyIterator extends SubMapIterator<K> { |
1661 |
|
public K next() { |
1662 |
|
return prevEntry().key; |
1663 |
|
} |
1664 |
+ |
public void remove() { |
1665 |
+ |
removeDescending(); |
1666 |
+ |
} |
1667 |
|
} |
1668 |
|
} |
1669 |
|
|
1695 |
|
} |
1696 |
|
|
1697 |
|
public NavigableMap<K,V> headMap(K toKey, boolean inclusive) { |
1698 |
< |
if (!inClosedRange(toKey)) |
1698 |
> |
if (!inRange(toKey, inclusive)) |
1699 |
|
throw new IllegalArgumentException("toKey out of range"); |
1700 |
|
return new AscendingSubMap(m, |
1701 |
|
fromStart, lo, loInclusive, |
2359 |
|
|
2360 |
|
if (hi < lo) return null; |
2361 |
|
|
2362 |
< |
int mid = (lo + hi) / 2; |
2362 |
> |
int mid = (lo + hi) >>> 1; |
2363 |
|
|
2364 |
|
Entry<K,V> left = null; |
2365 |
|
if (lo < mid) |