-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Closed
Description
Looks like using Iterator.remove before Entry.setValue is not correct. remove can substitute some TreeNodes in HashMap to plain Nodes, while iterator continues to iterate over old TreeNode instances and sets the values to those garbage nodes.
public class Main {
static class Key {
@Override
public int hashCode() {
return 0; // to put keys in one bucket
}
}
public static void main(String[] args) {
List<Key> keys = new ArrayList<>();
for (int i = 0; i < 11; ++i) { // 11 is big enough for a map to use tree nodes
keys.add(new Key());
}
Map<Object, Object> data = Collections.singletonMap(keys.get(10), 1);
Map<Object, Object> result = new HashMap<>();
for (Object key : keys) {
result.put(key, null);
}
for (Iterator<Map.Entry<Object, Object>> iter = result.entrySet().iterator(); iter.hasNext();) {
Map.Entry<Object, Object> entry = iter.next();
Object value = data.get(entry.getKey());
if (value == null) {
iter.remove();
} else {
entry.setValue(value); // this call doesn't set the value
}
}
if (result.containsValue(null)) {
System.out.println("FAILED");
} else {
System.out.println("OK");
}
}
}
Metadata
Metadata
Assignees
Labels
No labels