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.