Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Java: What happens if I change a key in an HashMap to be equal to another key? [duplicate]

I know that I can not have 2 keys in a HashMap which are equal (by the equals()-method). And if I try to add a key-value-pair to the HashMap with the key already existing, the old value is just replaced by the new one.

But what if I change an already existing key to be equal to another existing key?

How will the map.get() method behave in this case (applied to one of these equal keys)?

Very simple example below.

public class Person{
  private int age;
  private String name;

  public Person(int a, String n){
    age = a;
    name = n;
  }

  public void setAge(int a){ age = a; }
  public int getAge(){return age; }
  public String getName() {return name; }

  @Override
  public boolean equals(Object o){
     if(!(o instanceof Person)){return false;}
     Person p = (Person) o;
     return ((p.getName().equals(this.getName())) && (p.getAge() == this.getAge()));
  }

  @Override
  public int hashCode(){return age;}
}

public class MainClass{
 public static void main(String[]args){
   Person p1 = new Person("Bill", 20);
   Person p2 = new Person("Bill", 21); 
   HashMap<Person, String> map = new HashMap<>();
   map.put(p1, "some value");
   map.put(p2, "another value");
   p1.setAge(21);
   String x = map.get(p1); // <-- What will this be??
   System.out.println(x);  
 }

}
like image 948
DanielBK Avatar asked Sep 18 '17 10:09

DanielBK


2 Answers

When you mutate a key which is already present in the HashMap you break the HashMap. You are not supposed to mutate keys present in the HashMap. If you must mutate such keys, you should remove them from the HashMap before the change, and put them again in the HashMap after the change.

map.get(p1) will search for the key p1 according to its new hashCode, which is equal to the hash code of p2. Therefore it will search in the bucket that contains p2, and return the corresponding value - "another value" (unless both keys happen to be mapped to the same bucket, in which case either value can be returned, depending on which key would be tested first for equality).

like image 122
Eran Avatar answered Sep 24 '22 08:09

Eran


In short: p1 will not be reachable anymore.

In general the map is using the hash function to split the keys to buckets and then the equal function to locate the correct key-value. when you change the value of p1 and with that its hash value. If you will look for it the map will look for the value in a different bucket and will not see it and the p1 that is in the map will not be reachable.

like image 31
Roee Gavirel Avatar answered Sep 22 '22 08:09

Roee Gavirel