Joshua Bloch wrote:
Folks,
While we're at it, here's another Collections bug discovered recently
by a Googler (Scott Blum). The value of this expression should be false:
new IdentityHashMap().containsValue(null)
Unfortunately, it's true. Looking at the code for containsValue, it's
obvious what's wrong:
/**
* Tests whether the specified object reference is a value in this
identity
* hash map.
*
* @param value value whose presence in this map is to be tested
* @return <tt>true</tt> if this map maps one or more keys to the
* specified object reference
* @see #containsKey(Object)
*/
public boolean containsValue(Object value) {
Object[] tab = table;
for (int i = 1; i < tab.length; i+= 2)
if (tab[i] == value)
return true;
return false;
}
Empty entries are masquerading as entries mapping to null. The fix is
easy:
if (tab[i] == value)
becomes:
if (tab[i] == value && tab[i -1] != null)
(Recall that the null key (but not value) is proxied by NULL_KEY.)
Josh
I don't see this in the bug database so I've created the following so
that it doesn't get lost:
6691215: (coll) IdentityHashMap.containsValue(null) returns true when
null value not present
-Alan.