Skip to content

Commit

Permalink
Fixed Map.entrySet.contains(o) to use reference equality
Browse files Browse the repository at this point in the history
  • Loading branch information
ben-manes committed Nov 29, 2021
1 parent 1eed56b commit 76349c2
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.OptionalLong;
Expand Down Expand Up @@ -3134,8 +3133,13 @@ public boolean contains(Object obj) {
return false;
}
Entry<?, ?> entry = (Entry<?, ?>) obj;
Node<K, V> node = cache.data.get(cache.nodeFactory.newLookupKey(entry.getKey()));
return (node != null) && Objects.equals(node.getValue(), entry.getValue());
Object key = entry.getKey();
Object value = entry.getValue();
if ((key == null) || (value == null)) {
return false;
}
Node<K, V> node = cache.data.get(cache.nodeFactory.newLookupKey(key));
return (node != null) && node.containsValue(value);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1002,8 +1002,13 @@ public boolean contains(Object o) {
return false;
}
Entry<?, ?> entry = (Entry<?, ?>) o;
V value = AsMapView.this.get(entry.getKey());
return (value != null) && value.equals(entry.getValue());
Object key = entry.getKey();
Object value = entry.getValue();
if ((key == null) || (value == null)) {
return false;
}
V cachedValue = AsMapView.this.get(key);
return (cachedValue != null) && cachedValue.equals(value);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -733,8 +733,13 @@ public boolean contains(Object o) {
return false;
}
Entry<?, ?> entry = (Entry<?, ?>) o;
V value = cache.get(entry.getKey());
return (value != null) && value.equals(entry.getValue());
Object key = entry.getKey();
Object value = entry.getValue();
if ((key == null) || (value == null)) {
return false;
}
V cachedValue = cache.get(key);
return (cachedValue != null) && cachedValue.equals(value);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;

import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
Expand Down Expand Up @@ -2163,6 +2164,43 @@ public void entriesToArray(Map<Integer, Integer> map, CacheContext context) {
assertThat(Arrays.asList(array).containsAll(context.original().entrySet()), is(true));
}

@CheckNoStats
@Test(dataProvider = "caches")
@CacheSpec(population = Population.FULL,
removalListener = { Listener.DEFAULT, Listener.REJECTING })
public void entrySet_contains_nullKey(Map<Integer, Integer> map, CacheContext context) {
Map.Entry<Integer, Integer> entry = new AbstractMap.SimpleEntry<>(
null, context.original().get(context.firstKey()));
assertThat(map.entrySet().contains(entry), is(false));
}

@CheckNoStats
@Test(dataProvider = "caches")
@CacheSpec(population = Population.FULL,
removalListener = { Listener.DEFAULT, Listener.REJECTING })
public void entrySet_contains_nullValue(Map<Integer, Integer> map, CacheContext context) {
Map.Entry<Integer, Integer> entry = new AbstractMap.SimpleEntry<>(context.firstKey(), null);
assertThat(map.entrySet().contains(entry), is(false));
}

@CheckNoStats
@Test(dataProvider = "caches")
@CacheSpec(removalListener = { Listener.DEFAULT, Listener.REJECTING })
public void entrySet_contains_absent(Map<Integer, Integer> map, CacheContext context) {
Map.Entry<Integer, Integer> entry = immutableEntry(context.absentKey(), context.absentValue());
assertThat(map.entrySet().contains(entry), is(false));
}

@CheckNoStats
@Test(dataProvider = "caches")
@CacheSpec(population = Population.FULL,
removalListener = { Listener.DEFAULT, Listener.REJECTING })
public void entrySet_contains_present(Map<Integer, Integer> map, CacheContext context) {
Map.Entry<Integer, Integer> entry = immutableEntry(
context.firstKey(), context.original().get(context.firstKey()));
assertThat(map.entrySet().contains(entry), is(true));
}

@CheckNoWriter @CheckNoStats
@Test(dataProvider = "caches")
@CacheSpec(population = Population.EMPTY,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;

import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
Expand Down Expand Up @@ -1692,6 +1693,45 @@ public void entrySet_empty(AsyncCache<Integer, Integer> cache, CacheContext cont
assertThat(cache.asMap().entrySet(), is(deeplyEmpty()));
}

@CheckNoStats
@Test(dataProvider = "caches")
@CacheSpec(population = Population.FULL,
removalListener = { Listener.DEFAULT, Listener.REJECTING })
public void entrySet_contains_nullKey(AsyncCache<Integer, Integer> cache, CacheContext context) {
Map.Entry<Integer, CompletableFuture<Integer>> entry =
new AbstractMap.SimpleEntry<>(null, cache.asMap().get(context.firstKey()));
assertThat(cache.asMap().entrySet().contains(entry), is(false));
}

@CheckNoStats
@Test(dataProvider = "caches")
@CacheSpec(population = Population.FULL,
removalListener = { Listener.DEFAULT, Listener.REJECTING })
public void entrySet_contains_nullValue(AsyncCache<Integer, Integer> cache, CacheContext context) {
Map.Entry<Integer, CompletableFuture<Integer>> entry =
new AbstractMap.SimpleEntry<>(context.firstKey(), null);
assertThat(cache.asMap().entrySet().contains(entry), is(false));
}

@CheckNoStats
@Test(dataProvider = "caches")
@CacheSpec(removalListener = { Listener.DEFAULT, Listener.REJECTING })
public void entrySet_contains_absent(AsyncCache<Integer, Integer> cache, CacheContext context) {
Map.Entry<Integer, CompletableFuture<Integer>> entry = immutableEntry(
context.absentKey(), CompletableFuture.completedFuture(context.absentValue()));
assertThat(cache.asMap().entrySet().contains(entry), is(false));
}

@CheckNoStats
@Test(dataProvider = "caches")
@CacheSpec(population = Population.FULL,
removalListener = { Listener.DEFAULT, Listener.REJECTING })
public void entrySet_contains_present(AsyncCache<Integer, Integer> cache, CacheContext context) {
Map.Entry<Integer, CompletableFuture<Integer>> entry = immutableEntry(
context.firstKey(), cache.asMap().get(context.firstKey()));
assertThat(cache.asMap().entrySet().contains(entry), is(true));
}

@CheckNoStats
@CacheSpec(population = Population.EMPTY, removalListener = Listener.DEFAULT)
@Test(dataProvider = "caches", expectedExceptions = UnsupportedOperationException.class)
Expand Down

0 comments on commit 76349c2

Please sign in to comment.