简体   繁体   中英

Custom object as Map key

AS I have read that if custom objects need to be the key of map, hashcode and equals method need to override, but in my case its working without overriding it. Could someone please tell whats getting wrong ?

    Map<Student,Integer> map = new HashMap<>();
    Student s1=new Student(1,"A");
    Student s2=new Student(2,"B");
    Student s3=new Student(3,"C");

    map.put(s1,1);
    map.put(s2,2);
    map.put(s1,3);

    for(Student s:map.keySet()) {
        System.out.println(map.get(s) + "->" + s.id + " " +s.name);
    }

Proper output:

3-> 1 A

2-> 2 B

It is one of the properties of equals method: it is reflexive. Which means that

x.equals(x) == true 

An object is always equal to itself. In this case you are relaying on default implementation of equals method.

map.put(s1,1); 
map.put(s1,3);

and because the default implementation is reflexive

s1.equals(s1) == true 

value 1 is replaced with 3

However result will be different if you will do something like this

map.put(new Student(1,"A"),3);

s1.equals(new Student(1,"A")); 

You will need to override hashCode and equals to make it work properly.

If there is no overriding hashCode nor equals method, Java compares object references. Thus, s1 reference is the same as s1 reference, so you can replace s1 associated value with another.

If you create a new Student object with the same attributes values than s1 , and try to insert it into your map, you'll have two different pairs.

Built-in hashCode() and equals() works fine. They're consistent in the way required by HashMap (ie: if hashCode() s aren't identical, equals() will always return false ). That's because every object instance will only be equal() to itself.

However this is often not what you want it to do. Specifically, without overriding these methods, two instances of Student with identical fields will not be considered equal. So this will print out three lines instead of one:

Map<Student,Integer> map = new HashMap<>();
Student s1=new Student(1,"A");
Student s2=new Student(1,"A");
Student s3=new Student(1,"A");

map.put(s1,1);
map.put(s2,2);
map.put(s3,3);

for(Student s:map.keySet()) {
    System.out.println(map.get(s) + "->" + s.id + " " +s.name);
}

(Note: technically this is all perfectly correct, but is not necessarily what most people reading your code would expect to happen.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM