Java HashMap return value not confirming with my understanding of equals and hashcode

不羁的心 提交于 2019-12-02 12:43:46

问题


The output of the following code sample is:

{1--e=e2, 2--e1=e1}

package com.sid.practice;

import java.util.HashMap;
import java.util.Map;

public class InputOutputPractice 
{

    public InputOutputPractice() 
    {

    }

    public static void main(String[] args) 
    {
        Employee e = new InputOutputPractice().new Employee(1, "e");
        Employee e1 = new InputOutputPractice().new Employee(2, "e1");
        Employee e2 = new InputOutputPractice().new Employee(1, "e2");

        Map m = new HashMap();
        m.put(e, "e");
        m.put(e1, "e1");
        m.put(e2, "e2");
        System.out.println(m);

    }

    class Employee
    {
        public Employee(int id, String name)
        {
            this.id=id;
            this.name = name;
        }

        private int id;
        private String name;

        public String getName() 
        {
            return name;
        }

        public void setName(String name) 
        {
            this.name = name;
        }

        public int getId() 
        {
            return id;
        }

        public void setId(int id) 
        {
            this.id = id;
        }

        @Override
        public boolean equals(Object obj) 
        {
            return ((Employee)obj).getId()==(this.getId());
        }

        @Override
        public int hashCode() 
        {
            return Integer.valueOf(getId()).hashCode();
        }

        @Override
        public String toString() 
        {
            return this.id + "--" + this.name;
        }
    }
}

I do not understand how the Object e2 was able to overwrite the key in Object e, but not the value. In my understanding the output should have been:

{1--e2=e2, 2--e1=e1}


回答1:


Actually, you got it backwards. The value was overridden. The key wasn't replaced since as far as HashMap is concerned, e and e2 are identical.

Your output is {1--e=e2, 2--e1=e1}:

key = e, value = "e2" (which overrode the old value "e")
key = e1, value = "e1" 



回答2:


The Javadocs for HashMap state for the put method:

Associates the specified value with the specified key in this map. If the map previously contained a mapping for the key, the old value is replaced.

Hence, the key is not overwritten, only the value.




回答3:


The java.util.HashMap implementation does not replace the existing key when it is equal to the key supplied in the put() call. So, your third put() checks the existing contents of the map, finds an existing equal key and just updates the associated value.

This illustrates why equals() and hashCode() should generally take all properties into account as objects which are considered equal are considered interchangeable by many of the util classes.




回答4:


The reason behind the output {1--e=e2, 2--e1=e1} is :

Map do not replaces key it only does so for value when there is match (present on the basis of key) in the existing Map. So applies in this case:

Here e is equal to e2 for Map. When Map search for location to put m.put(e2, "e2"); it goes to location where e--"e1" is present and replaces "e1" by "e2" and leaves the key i.e e in this case intact



来源:https://stackoverflow.com/questions/27147325/java-hashmap-return-value-not-confirming-with-my-understanding-of-equals-and-has

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!