With many years in the software development, we all have some fire side stories to share. These range from deleted files, chasing elusive bugs, that all night effort to meet a deadline. In the following series, I recollect some of these tales. The present article tells the story of how a HashMap randomly made the objects disappear!
Problem
We had a HashMap which held a few entries with keys of type Person and the values of type String holding company's name. After adding these entries to the HashMap we noticed that some of them randomly disappeared - that is - we could not retrieve the Company Name String (value) even passing the Person (key) that was used to add the entry!
I have included the sources of Person.java and HashMapStore.java for your debugging pleasure :-) Sleuth on - solution is at the end.
Source Code - HashMapStore.java
import java.util.HashMap;
public class HashMapStore {
public static void main(String[] args) {
Person sai = new Person("Sai Matam", 35, "Coding");
Person bill = new Person("Bill", 45, "Fishing");
Person don = new Person("Don", 55, "Reading");
HashMap < Person, String > hashMap = new HashMap < Person, String > ();
hashMap.put(sai, "Grand Binary Inc.");
hashMap.put(bill, "Super Coders Inc.");
hashMap.put(don, "Great Software Inc. ");
String saiCompany = hashMap.get(sai);
System.out.println("\nSearch for sai's company: " + saiCompany);
String processedName = sai.getName().replace(' ', '_');
sai.setName(processedName);
processedName = bill.getName().replace(' ', '_');
bill.setName(processedName);
processedName = don.getName().replace(' ', '_');
don.setName(processedName);
saiCompany = hashMap.get(sai);
System.out.println("Let's search for sai's company again: " + saiCompany + "\n\n");
}
}
Source Code - Person.java
public class Person {
private String name;
private int age;
private String hobby;
public Person(String name, int age, String hobby) {
this.name = name;
this.age = age;
this.hobby = hobby;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
public String getHobby() {
return this.hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
public int hashCode() {
return name.hashCode() + age + hobby.hashCode();
}
public boolean equals(Object otherObj) {
Person otherPerson = (Person) otherObj;
return ( name.equals(otherPerson.getName()) &&
hobby.equals(otherPerson.getHobby()) &&
age == otherPerson.getAge());
}
}
Output

Solution
Initially I suspected the hashCode() or equals() implemenation in the Person class. But they were okay. The culprit was in the HashStoreMap.java where the keys of the Person objects were being modified after they were inserted into the HashMap !!!
When the Person object was modified its hashCode() changed. So the next time HashMap searched for this key it looked under a different hash bucket and hence could not find the entry. So it returned 'null' !! Mystery solved.
Conclusion
Never change the object used as a key in a HashMap. It would be a good practice to make this key object immutable.
If you liked this article then please vote for this article by clicking on the green up arrow.
Your feedback is most valuable. Please use 'comments' or an e-mail to saimatam (at) yahoo (dot) com