56 import java.util.concurrent.ConcurrentNavigableMap; |
56 import java.util.concurrent.ConcurrentNavigableMap; |
57 import java.util.function.BiFunction; |
57 import java.util.function.BiFunction; |
58 import java.util.function.Consumer; |
58 import java.util.function.Consumer; |
59 import java.util.function.BiConsumer; |
59 import java.util.function.BiConsumer; |
60 import java.util.function.Function; |
60 import java.util.function.Function; |
|
61 import java.util.function.Predicate; |
61 |
62 |
62 /** |
63 /** |
63 * A scalable concurrent {@link ConcurrentNavigableMap} implementation. |
64 * A scalable concurrent {@link ConcurrentNavigableMap} implementation. |
64 * The map is sorted according to the {@linkplain Comparable natural |
65 * The map is sorted according to the {@linkplain Comparable natural |
65 * ordering} of its keys, or by a {@link Comparator} provided at map |
66 * ordering} of its keys, or by a {@link Comparator} provided at map |
2490 if (m instanceof ConcurrentSkipListMap) |
2491 if (m instanceof ConcurrentSkipListMap) |
2491 return ((ConcurrentSkipListMap<?,E>)m).valueSpliterator(); |
2492 return ((ConcurrentSkipListMap<?,E>)m).valueSpliterator(); |
2492 else |
2493 else |
2493 return (Spliterator<E>)((SubMap<?,E>)m).valueIterator(); |
2494 return (Spliterator<E>)((SubMap<?,E>)m).valueIterator(); |
2494 } |
2495 } |
|
2496 public boolean removeIf(Predicate<? super E> filter) { |
|
2497 if (filter == null) throw new NullPointerException(); |
|
2498 if (m instanceof ConcurrentSkipListMap) |
|
2499 return ((ConcurrentSkipListMap<?,E>)m).removeValueIf(filter); |
|
2500 // else use iterator |
|
2501 @SuppressWarnings("unchecked") Iterator<Map.Entry<Object,E>> it = |
|
2502 ((SubMap<Object,E>)m).entryIterator(); |
|
2503 boolean removed = false; |
|
2504 while (it.hasNext()) { |
|
2505 Map.Entry<Object,E> e = it.next(); |
|
2506 E v = e.getValue(); |
|
2507 if (filter.test(v) && m.remove(e.getKey(), v)) |
|
2508 removed = true; |
|
2509 } |
|
2510 return removed; |
|
2511 } |
2495 } |
2512 } |
2496 |
2513 |
2497 static final class EntrySet<K1,V1> extends AbstractSet<Map.Entry<K1,V1>> { |
2514 static final class EntrySet<K1,V1> extends AbstractSet<Map.Entry<K1,V1>> { |
2498 final ConcurrentNavigableMap<K1, V1> m; |
2515 final ConcurrentNavigableMap<K1, V1> m; |
2499 EntrySet(ConcurrentNavigableMap<K1, V1> map) { |
2516 EntrySet(ConcurrentNavigableMap<K1, V1> map) { |
2551 if (m instanceof ConcurrentSkipListMap) |
2568 if (m instanceof ConcurrentSkipListMap) |
2552 return ((ConcurrentSkipListMap<K1,V1>)m).entrySpliterator(); |
2569 return ((ConcurrentSkipListMap<K1,V1>)m).entrySpliterator(); |
2553 else |
2570 else |
2554 return (Spliterator<Map.Entry<K1,V1>>) |
2571 return (Spliterator<Map.Entry<K1,V1>>) |
2555 ((SubMap<K1,V1>)m).entryIterator(); |
2572 ((SubMap<K1,V1>)m).entryIterator(); |
|
2573 } |
|
2574 public boolean removeIf(Predicate<? super Entry<K1, V1>> filter) { |
|
2575 if (filter == null) throw new NullPointerException(); |
|
2576 if (m instanceof ConcurrentSkipListMap) |
|
2577 return ((ConcurrentSkipListMap<K1,V1>)m).removeEntryIf(filter); |
|
2578 // else use iterator |
|
2579 Iterator<Map.Entry<K1,V1>> it = ((SubMap<K1,V1>)m).entryIterator(); |
|
2580 boolean removed = false; |
|
2581 while (it.hasNext()) { |
|
2582 Map.Entry<K1,V1> e = it.next(); |
|
2583 if (filter.test(e) && m.remove(e.getKey(), e.getValue())) |
|
2584 removed = true; |
|
2585 } |
|
2586 return removed; |
2556 } |
2587 } |
2557 } |
2588 } |
2558 |
2589 |
2559 /** |
2590 /** |
2560 * Submaps returned by {@link ConcurrentSkipListMap} submap operations |
2591 * Submaps returned by {@link ConcurrentSkipListMap} submap operations |
3265 } |
3296 } |
3266 } |
3297 } |
3267 } |
3298 } |
3268 |
3299 |
3269 /** |
3300 /** |
|
3301 * Helper method for EntrySet.removeIf |
|
3302 */ |
|
3303 boolean removeEntryIf(Predicate<? super Entry<K, V>> function) { |
|
3304 if (function == null) throw new NullPointerException(); |
|
3305 boolean removed = false; |
|
3306 for (Node<K,V> n = findFirst(); n != null; n = n.next) { |
|
3307 V v; |
|
3308 if ((v = n.getValidValue()) != null) { |
|
3309 K k = n.key; |
|
3310 Map.Entry<K,V> e = new AbstractMap.SimpleImmutableEntry<>(k, v); |
|
3311 if (function.test(e) && remove(k, v)) |
|
3312 removed = true; |
|
3313 } |
|
3314 } |
|
3315 return removed; |
|
3316 } |
|
3317 |
|
3318 /** |
|
3319 * Helper method for Values.removeIf |
|
3320 */ |
|
3321 boolean removeValueIf(Predicate<? super V> function) { |
|
3322 if (function == null) throw new NullPointerException(); |
|
3323 boolean removed = false; |
|
3324 for (Node<K,V> n = findFirst(); n != null; n = n.next) { |
|
3325 V v; |
|
3326 if ((v = n.getValidValue()) != null) { |
|
3327 K k = n.key; |
|
3328 if (function.test(v) && remove(k, v)) |
|
3329 removed = true; |
|
3330 } |
|
3331 } |
|
3332 return removed; |
|
3333 } |
|
3334 |
|
3335 /** |
3270 * Base class providing common structure for Spliterators. |
3336 * Base class providing common structure for Spliterators. |
3271 * (Although not all that much common functionality; as usual for |
3337 * (Although not all that much common functionality; as usual for |
3272 * view classes, details annoyingly vary in key, value, and entry |
3338 * view classes, details annoyingly vary in key, value, and entry |
3273 * subclasses in ways that are not worth abstracting out for |
3339 * subclasses in ways that are not worth abstracting out for |
3274 * internal classes.) |
3340 * internal classes.) |