488 |
|
V v = getValidValue(); |
489 |
|
if (v == null) |
490 |
|
return null; |
491 |
< |
return new AbstractMap.SimpleImmutableEntry(key, v); |
491 |
> |
return new AbstractMap.SimpleImmutableEntry<K,V>(key, v); |
492 |
|
} |
493 |
|
} |
494 |
|
|
614 |
|
private Comparable<? super K> comparable(Object key) throws ClassCastException { |
615 |
|
if (key == null) |
616 |
|
throw new NullPointerException(); |
617 |
< |
return (comparator != null) |
618 |
< |
? new ComparableUsingComparator(key, comparator) |
619 |
< |
: (Comparable<? super K>)key; |
617 |
> |
if (comparator != null) |
618 |
> |
return new ComparableUsingComparator<K>((K)key, comparator); |
619 |
> |
else |
620 |
> |
return (Comparable<? super K>)key; |
621 |
|
} |
622 |
|
|
623 |
|
/** |
1418 |
|
} |
1419 |
|
|
1420 |
|
/** |
1421 |
< |
* Returns SimpleImmutableEntry or key for results of findNear |
1422 |
< |
* after screening to ensure result is in given range. Needed by |
1422 |
< |
* submaps. |
1421 |
> |
* Returns key for results of findNear after screening to ensure |
1422 |
> |
* result is in given range. Needed by submaps. |
1423 |
|
* @param kkey the key |
1424 |
|
* @param rel the relation -- OR'ed combination of EQ, LT, GT |
1425 |
|
* @param least minimum allowed key value |
1426 |
|
* @param fence key greater than maximum allowed key value |
1427 |
< |
* @param keyOnly if true return key, else return SimpleImmutableEntry |
1428 |
< |
* @return Key or Entry fitting relation, or <tt>null</tt> if no such |
1427 |
> |
* @return Key fitting relation, or <tt>null</tt> if no such |
1428 |
|
*/ |
1429 |
< |
Object getNear(K kkey, int rel, K least, K fence, boolean keyOnly) { |
1429 |
> |
K getNearKey(K kkey, int rel, K least, K fence) { |
1430 |
|
K key = kkey; |
1431 |
|
// Don't return keys less than least |
1432 |
|
if ((rel & LT) == 0) { |
1442 |
|
return null; |
1443 |
|
K k = n.key; |
1444 |
|
V v = n.getValidValue(); |
1445 |
< |
if (v != null) { |
1446 |
< |
if (keyOnly) |
1447 |
< |
return k; |
1448 |
< |
else |
1449 |
< |
return new AbstractMap.SimpleImmutableEntry<K,V>(k, v); |
1445 |
> |
if (v != null) |
1446 |
> |
return k; |
1447 |
> |
} |
1448 |
> |
} |
1449 |
> |
|
1450 |
> |
|
1451 |
> |
/** |
1452 |
> |
* Returns SimpleImmutableEntry for results of findNear after |
1453 |
> |
* screening to ensure result is in given range. Needed by |
1454 |
> |
* submaps. |
1455 |
> |
* @param kkey the key |
1456 |
> |
* @param rel the relation -- OR'ed combination of EQ, LT, GT |
1457 |
> |
* @param least minimum allowed key value |
1458 |
> |
* @param fence key greater than maximum allowed key value |
1459 |
> |
* @return Entry fitting relation, or <tt>null</tt> if no such |
1460 |
> |
*/ |
1461 |
> |
Map.Entry<K,V> getNearEntry(K kkey, int rel, K least, K fence) { |
1462 |
> |
K key = kkey; |
1463 |
> |
// Don't return keys less than least |
1464 |
> |
if ((rel & LT) == 0) { |
1465 |
> |
if (compare(key, least) < 0) { |
1466 |
> |
key = least; |
1467 |
> |
rel = rel | EQ; |
1468 |
|
} |
1469 |
|
} |
1470 |
+ |
|
1471 |
+ |
for (;;) { |
1472 |
+ |
Node<K,V> n = findNear(key, rel); |
1473 |
+ |
if (n == null || !inHalfOpenRange(n.key, least, fence)) |
1474 |
+ |
return null; |
1475 |
+ |
K k = n.key; |
1476 |
+ |
V v = n.getValidValue(); |
1477 |
+ |
if (v != null) |
1478 |
+ |
return new AbstractMap.SimpleImmutableEntry<K,V>(k, v); |
1479 |
+ |
} |
1480 |
|
} |
1481 |
|
|
1482 |
|
/** |
1483 |
|
* Finds and removes least element of subrange. |
1484 |
|
* @param least minimum allowed key value |
1485 |
|
* @param fence key greater than maximum allowed key value |
1486 |
< |
* @param keyOnly if true return key, else return SimpleImmutableEntry |
1460 |
< |
* @return least Key or Entry, or <tt>null</tt> if no such |
1486 |
> |
* @return least Entry, or <tt>null</tt> if no such |
1487 |
|
*/ |
1488 |
< |
Object removeFirstEntryOfSubrange(K least, K fence, boolean keyOnly) { |
1488 |
> |
Map.Entry<K,V> removeFirstEntryOfSubrange(K least, K fence) { |
1489 |
|
for (;;) { |
1490 |
|
Node<K,V> n = findCeiling(least); |
1491 |
|
if (n == null) |
1494 |
|
if (fence != null && compare(k, fence) >= 0) |
1495 |
|
return null; |
1496 |
|
V v = doRemove(k, null); |
1497 |
< |
if (v != null) { |
1498 |
< |
if (keyOnly) |
1473 |
< |
return k; |
1474 |
< |
else |
1475 |
< |
return new AbstractMap.SimpleImmutableEntry<K,V>(k, v); |
1476 |
< |
} |
1497 |
> |
if (v != null) |
1498 |
> |
return new AbstractMap.SimpleImmutableEntry<K,V>(k, v); |
1499 |
|
} |
1500 |
|
} |
1501 |
|
|
1503 |
|
* Finds and removes greatest element of subrange. |
1504 |
|
* @param least minimum allowed key value |
1505 |
|
* @param fence key greater than maximum allowed key value |
1506 |
< |
* @param keyOnly if true return key, else return SimpleImmutableEntry |
1485 |
< |
* @return least Key or Entry, or <tt>null</tt> if no such |
1506 |
> |
* @return least Entry, or <tt>null</tt> if no such |
1507 |
|
*/ |
1508 |
< |
Object removeLastEntryOfSubrange(K least, K fence, boolean keyOnly) { |
1508 |
> |
Map.Entry removeLastEntryOfSubrange(K least, K fence) { |
1509 |
|
for (;;) { |
1510 |
|
Node<K,V> n = findLower(fence); |
1511 |
|
if (n == null) |
1514 |
|
if (least != null && compare(k, least) < 0) |
1515 |
|
return null; |
1516 |
|
V v = doRemove(k, null); |
1517 |
< |
if (v != null) { |
1518 |
< |
if (keyOnly) |
1498 |
< |
return k; |
1499 |
< |
else |
1500 |
< |
return new AbstractMap.SimpleImmutableEntry<K,V>(k, v); |
1501 |
< |
} |
1517 |
> |
if (v != null) |
1518 |
> |
return new AbstractMap.SimpleImmutableEntry<K,V>(k, v); |
1519 |
|
} |
1520 |
|
} |
1521 |
|
|
1522 |
+ |
|
1523 |
+ |
|
1524 |
|
/* ---------------- Constructors -------------- */ |
1525 |
|
|
1526 |
|
/** |
2167 |
|
public ConcurrentNavigableMap<K,V> navigableSubMap(K fromKey, K toKey) { |
2168 |
|
if (fromKey == null || toKey == null) |
2169 |
|
throw new NullPointerException(); |
2170 |
< |
return new ConcurrentSkipListSubMap(this, fromKey, toKey); |
2170 |
> |
return new ConcurrentSkipListSubMap<K,V>(this, fromKey, toKey); |
2171 |
|
} |
2172 |
|
|
2173 |
|
/** |
2178 |
|
public ConcurrentNavigableMap<K,V> navigableHeadMap(K toKey) { |
2179 |
|
if (toKey == null) |
2180 |
|
throw new NullPointerException(); |
2181 |
< |
return new ConcurrentSkipListSubMap(this, null, toKey); |
2181 |
> |
return new ConcurrentSkipListSubMap<K,V>(this, null, toKey); |
2182 |
|
} |
2183 |
|
|
2184 |
|
/** |
2189 |
|
public ConcurrentNavigableMap<K,V> navigableTailMap(K fromKey) { |
2190 |
|
if (fromKey == null) |
2191 |
|
throw new NullPointerException(); |
2192 |
< |
return new ConcurrentSkipListSubMap(this, fromKey, null); |
2192 |
> |
return new ConcurrentSkipListSubMap<K,V>(this, fromKey, null); |
2193 |
|
} |
2194 |
|
|
2195 |
|
/** |
2871 |
|
public Object[] toArray() { |
2872 |
|
Collection<Map.Entry<K,V>> c = new ArrayList<Map.Entry<K,V>>(); |
2873 |
|
for (Map.Entry e : this) |
2874 |
< |
c.add(new AbstractMap.SimpleEntry(e.getKey(), e.getValue())); |
2874 |
> |
c.add(new AbstractMap.SimpleEntry<K,V>((K)e.getKey(), (V)e.getValue())); |
2875 |
|
return c.toArray(); |
2876 |
|
} |
2877 |
|
public <T> T[] toArray(T[] a) { |
2878 |
|
Collection<Map.Entry<K,V>> c = new ArrayList<Map.Entry<K,V>>(); |
2879 |
|
for (Map.Entry e : this) |
2880 |
< |
c.add(new AbstractMap.SimpleEntry(e.getKey(), e.getValue())); |
2880 |
> |
c.add(new AbstractMap.SimpleEntry<K,V>((K)e.getKey(), (V)e.getValue())); |
2881 |
|
return c.toArray(a); |
2882 |
|
} |
2883 |
|
} |
3099 |
|
throw new NullPointerException(); |
3100 |
|
if (!inOpenRange(fromKey) || !inOpenRange(toKey)) |
3101 |
|
throw new IllegalArgumentException("key out of range"); |
3102 |
< |
return new ConcurrentSkipListSubMap(m, fromKey, toKey); |
3102 |
> |
return new ConcurrentSkipListSubMap<K,V>(m, fromKey, toKey); |
3103 |
|
} |
3104 |
|
|
3105 |
|
public ConcurrentNavigableMap<K,V> navigableHeadMap(K toKey) { |
3107 |
|
throw new NullPointerException(); |
3108 |
|
if (!inOpenRange(toKey)) |
3109 |
|
throw new IllegalArgumentException("key out of range"); |
3110 |
< |
return new ConcurrentSkipListSubMap(m, least, toKey); |
3110 |
> |
return new ConcurrentSkipListSubMap<K,V>(m, least, toKey); |
3111 |
|
} |
3112 |
|
|
3113 |
|
public ConcurrentNavigableMap<K,V> navigableTailMap(K fromKey) { |
3115 |
|
throw new NullPointerException(); |
3116 |
|
if (!inOpenRange(fromKey)) |
3117 |
|
throw new IllegalArgumentException("key out of range"); |
3118 |
< |
return new ConcurrentSkipListSubMap(m, fromKey, fence); |
3118 |
> |
return new ConcurrentSkipListSubMap<K,V>(m, fromKey, fence); |
3119 |
|
} |
3120 |
|
|
3121 |
|
public SortedMap<K,V> subMap(K fromKey, K toKey) { |
3133 |
|
/* ---------------- Relational methods -------------- */ |
3134 |
|
|
3135 |
|
public Map.Entry<K,V> ceilingEntry(K key) { |
3136 |
< |
return (Map.Entry<K,V>) |
3118 |
< |
m.getNear(key, m.GT|m.EQ, least, fence, false); |
3136 |
> |
return m.getNearEntry(key, m.GT|m.EQ, least, fence); |
3137 |
|
} |
3138 |
|
|
3139 |
|
public K ceilingKey(K key) { |
3140 |
< |
return (K) |
3123 |
< |
m.getNear(key, m.GT|m.EQ, least, fence, true); |
3140 |
> |
return m.getNearKey(key, m.GT|m.EQ, least, fence); |
3141 |
|
} |
3142 |
|
|
3143 |
|
public Map.Entry<K,V> lowerEntry(K key) { |
3144 |
< |
return (Map.Entry<K,V>) |
3128 |
< |
m.getNear(key, m.LT, least, fence, false); |
3144 |
> |
return m.getNearEntry(key, m.LT, least, fence); |
3145 |
|
} |
3146 |
|
|
3147 |
|
public K lowerKey(K key) { |
3148 |
< |
return (K) |
3133 |
< |
m.getNear(key, m.LT, least, fence, true); |
3148 |
> |
return m.getNearKey(key, m.LT, least, fence); |
3149 |
|
} |
3150 |
|
|
3151 |
|
public Map.Entry<K,V> floorEntry(K key) { |
3152 |
< |
return (Map.Entry<K,V>) |
3138 |
< |
m.getNear(key, m.LT|m.EQ, least, fence, false); |
3152 |
> |
return m.getNearEntry(key, m.LT|m.EQ, least, fence); |
3153 |
|
} |
3154 |
|
|
3155 |
|
public K floorKey(K key) { |
3156 |
< |
return (K) |
3143 |
< |
m.getNear(key, m.LT|m.EQ, least, fence, true); |
3156 |
> |
return m.getNearKey(key, m.LT|m.EQ, least, fence); |
3157 |
|
} |
3158 |
|
|
3146 |
– |
|
3159 |
|
public Map.Entry<K,V> higherEntry(K key) { |
3160 |
< |
return (Map.Entry<K,V>) |
3149 |
< |
m.getNear(key, m.GT, least, fence, false); |
3160 |
> |
return m.getNearEntry(key, m.GT, least, fence); |
3161 |
|
} |
3162 |
|
|
3163 |
|
public K higherKey(K key) { |
3164 |
< |
return (K) |
3154 |
< |
m.getNear(key, m.GT, least, fence, true); |
3164 |
> |
return m.getNearKey(key, m.GT, least, fence); |
3165 |
|
} |
3166 |
|
|
3167 |
|
public Map.Entry<K,V> firstEntry() { |
3187 |
|
} |
3188 |
|
|
3189 |
|
public Map.Entry<K,V> pollFirstEntry() { |
3190 |
< |
return (Map.Entry<K,V>) |
3181 |
< |
m.removeFirstEntryOfSubrange(least, fence, false); |
3190 |
> |
return m.removeFirstEntryOfSubrange(least, fence); |
3191 |
|
} |
3192 |
|
|
3193 |
|
public Map.Entry<K,V> pollLastEntry() { |
3194 |
< |
return (Map.Entry<K,V>) |
3186 |
< |
m.removeLastEntryOfSubrange(least, fence, false); |
3194 |
> |
return m.removeLastEntryOfSubrange(least, fence); |
3195 |
|
} |
3196 |
|
|
3197 |
|
/* ---------------- Submap Views -------------- */ |
3308 |
|
public Object[] toArray() { |
3309 |
|
Collection<Map.Entry<K,V>> c = new ArrayList<Map.Entry<K,V>>(); |
3310 |
|
for (Map.Entry e : this) |
3311 |
< |
c.add(new AbstractMap.SimpleEntry(e.getKey(), e.getValue())); |
3311 |
> |
c.add(new AbstractMap.SimpleEntry<K,V>((K)e.getKey(), (V)e.getValue())); |
3312 |
|
return c.toArray(); |
3313 |
|
} |
3314 |
|
public <T> T[] toArray(T[] a) { |
3315 |
|
Collection<Map.Entry<K,V>> c = new ArrayList<Map.Entry<K,V>>(); |
3316 |
|
for (Map.Entry e : this) |
3317 |
< |
c.add(new AbstractMap.SimpleEntry(e.getKey(), e.getValue())); |
3317 |
> |
c.add(new AbstractMap.SimpleEntry<K,V>((K)e.getKey(), (V)e.getValue())); |
3318 |
|
return c.toArray(a); |
3319 |
|
} |
3320 |
|
} |