Review hash collisions, stable keys, identity hash codes, and reliable HashMap lookup with ten Java SE 25 questions and a runnable collision example.
Answer: If two objects are equal, they must produce the same hash code. The converse is false: unequal objects can share a hash code. A value class therefore needs a hash implementation compatible with its definition of equality. Hashing narrows a lookup; it does not prove that a matching object has been found.
Answer: Hash-based implementations such as HashMap and HashSet use them to organize keys or elements for lookup. Not every collection uses hashing: ArrayList generally scans for contains, and TreeMap uses comparisons. Read the contract and performance model of the chosen implementation.
Answer: It is a compact integer useful for distributing objects among hash-table locations. It is not a unique identifier, the object itself, or a universal bucket index. A table derives an internal location from the hash and its current capacity; resizing can change that location.
Answer: First use the lookup key hash to narrow the candidates. Then determine which candidate key actually matches, using identity or equality as appropriate. A collision does not cause one unrelated key to replace another.
Real implementations may mix hash bits, cache hashes, or use tree-shaped collision structures. The two-step explanation describes the idea rather than promising an exact internal algorithm.
import java.util.HashMap;
import java.util.Map;
public class HashCollisionExample {
record Key(String name) {
@Override public int hashCode() { return 7; }
}
public static void main(String[] args) {
Map<Key, String> map = new HashMap<>();
map.put(new Key("A"), "alpha");
map.put(new Key("B"), "beta");
System.out.println(map.size());
System.out.println(map.get(new Key("A")));
System.out.println(map.get(new Key("B")));
System.out.println(new Key("A").equals(new Key("B")));
}
}
The constant hash is intentional for this collision demonstration. It satisfies correctness but gives poor distribution. The record-generated equals still distinguishes the two names.
Answer: It returns int, a signed 32-bit value. Negative results are legal. The receiving data structure handles conversion to an internal index. Do not assume that taking an absolute value makes any hash a safe array index; Math.abs(Integer.MIN_VALUE) remains negative.
Answer: Their hash codes must match whenever the equality and hash-code contracts apply. They can be different instances. Two objects with different hash codes cannot be equal under a correct implementation, but matching hash codes alone tell you nothing conclusive about equality.
Answer: No. It supplies an identity-oriented hash with no uniqueness or memory-address guarantee. Different objects can collide. Changes to ordinary fields do not change the identity equality defined by Object. System.identityHashCode(object) obtains the identity hash even when the class overrides hashCode.
Answer: It must remain stable during an execution while equality-relevant information is unchanged, and equal objects must receive equal hashes. Good speed and distribution are desirable, but a constant hash is legal. The contract does not require every object to be immutable or every unequal pair to have distinct hashes.
A hash can change when equality-relevant state changes. That permission is not a reason to mutate a stored key: the collection does not automatically move an entry when its key changes.
Answer: The lookup object must be equal to a stored key and have the compatible hash required by that equality. The entry must still be present, and the stored key must not have changed in a way that invalidates its placement or comparisons. The collision example retrieves values with newly constructed, equal keys.
A null get result can mean either no mapping or a mapping to null. Use containsKey when you need to distinguish these cases.
Answer: Keep the hash stable while equality state is stable; give equal objects equal hashes; allow collisions between unequal objects. The contract does not require a particular value across separate application runs. Build the hash from the equality definition, not unrelated mutable counters or random values.
When repairing a key class, test equal copies, unequal values, collisions, and null handling as well as ordinary insertion. Immutability is a useful design technique for keeping collection keys reliable.
Java SE 25 references: Object, System, HashMap, Map, HashSet.