ConcurrentHashMultimap implements Multimap<K, V> { public boolean removeIf(K key, V value, Predicate<V> match) { final AtomicBoolean modified = new AtomicBoolean(false); final Object id = valueIdentityExtractor.apply(value); entries.compute(key, (ignored, values) -> { if (values == null) { modified.set(false); return null; } if (!values.containsKey(id)) { modified.set(false); return values; } V currentValue = values.get(id); if (!match.test(currentValue)) { modified.set(false); return values; } modified.set(true); Map<Object, V> newValues = CollectionsExt.copyAndRemove(values, id); if (newValues.isEmpty()) { return null; } return newValues; }); return modified.get(); } ConcurrentHashMultimap(ValueIdentityExtractor<V> valueIdentityExtractor, ConflictResolver<V> conflictResolver); @Override boolean put(@Nullable K key, @Nullable V value); @Override boolean remove(@Nullable Object key, @Nullable Object value); boolean removeIf(K key, V value, Predicate<V> match); @Override boolean putAll(@Nullable K key, Iterable<? extends V> values); @Override boolean putAll(Multimap<? extends K, ? extends V> values); @Override Collection<V> replaceValues(@Nullable K key, Iterable<? extends V> values); @Override Collection<V> removeAll(@Nullable Object key); @Override void clear(); @Override Collection<V> get(@Nullable K key); @Override Set<K> keySet(); @Override Multiset<K> keys(); @Override Collection<V> values(); @Override Collection<Map.Entry<K, V>> entries(); @Override int size(); @Override boolean isEmpty(); @Override boolean containsKey(@Nullable Object key); @Override boolean containsValue(@Nullable Object value); @Override boolean containsEntry(@Nullable Object key, @Nullable Object value); @Override Map<K, Collection<V>> asMap();  }
@Test public void removeIf() throws Exception { multiMap.put("first", new TestEntity("1", "v1")); multiMap.put("first", new TestEntity("2", "v2")); assertThat(multiMap.removeIf( "first", new TestEntity("1", "foo"), existing -> "foo".equals(existing.value)) ).isFalse(); assertThat(multiMap.get("first")).hasSize(2); assertThat(multiMap.removeIf( "first", new TestEntity("1", "foo"), existing -> "v1".equals(existing.value)) ).isTrue(); assertThat(multiMap.get("first")).hasSize(1) .doesNotContain(new TestEntity("1", "v1")); }