2017-02-09 23 views
0
package com.sample; 

import java.util.HashMap; 

class Student{ 
    int id; 

    @Override 
    public int hashCode() { 
     return -1; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     return false; // returning false 
    } 

} 

public class MainClass { 

    public static void main(String[] args) { 
     Student s1=new Student(); 
     s1.id=123; 
     Student s2=new Student(); 
     s2.id=456; 

     HashMap<Student,String> s=new HashMap<Student,String>(); 


     s.put(s1, "One"); 
     System.out.println(" < s1 value > "+s.get(s1) + " < s1 hashcode > "+s.get(s1).hashCode()); 
     s.put(s2, "Two"); 
     System.out.println(" < s2 value > "+s.get(s2) + " < s2 hashcode > "+s.get(s2).hashCode()); 
     s.put(s1, "Three"); 
     System.out.println(" < s1 value > "+s.get(s1) + " < s1 hashcode > "+s.get(s1).hashCode()); 

     System.out.println("after insert"); 

     System.out.println(" < s1 value > "+s.get(s1) + " < s1 hashcode > "+s.get(s1).hashCode()); 
     System.out.println(" < s2 value > "+s.get(s2) + " < s2 hashcode > "+s.get(s2).hashCode()); 


    } 

} 



OUTPUT 

< s1 value > One < s1 hashcode > 79430 
< s2 value > Two < s2 hashcode > 84524 
< s1 value > Three < s1 hashcode > 80786814 
after insert 
< s1 value > Three < s1 hashcode > 80786814 //printing three for s1 
< s2 value > Two < s2 hashcode > 84524 //printing two for s2 

//现在,如果我们改变equals方法的返回类型为true,输出的变化无一不返回三个作为输出。我无法理解,如果我们改变equals方法的返回类型,为什么输出会改变。请用bucket(HashMap)和equals方法的上下文来解释。如果我们改变equals方法的返回值,为什么输出会改变?

class Student{ 
    int id; 

    @Override 
    public int hashCode() { 
     return -1; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     return true; //returning true 
    } 

} 

public class MainClass { 

    public static void main(String[] args) { 
     Student s1=new Student(); 
     s1.id=123; 
     Student s2=new Student(); 
     s2.id=456; 

     HashMap<Student,String> s=new HashMap<Student,String>(); 


     s.put(s1, "One"); 
     System.out.println(" < s1 value > "+s.get(s1) + " < s1 hashcode > "+s.get(s1).hashCode()); 
     s.put(s2, "Two"); 
     System.out.println(" < s2 value > "+s.get(s2) + " < s2 hashcode > "+s.get(s2).hashCode()); 
     s.put(s1, "Three"); 
     System.out.println(" < s1 value > "+s.get(s1) + " < s1 hashcode > "+s.get(s1).hashCode()); 

     System.out.println("after insert"); 

     System.out.println(" < s1 value > "+s.get(s1) + " < s1 hashcode > "+s.get(s1).hashCode()); 
     System.out.println(" < s2 value > "+s.get(s2) + " < s2 hashcode > "+s.get(s2).hashCode()); 


    } 

} 


OUTPUT- 

< s1 value > One < s1 hashcode > 79430 
< s2 value > Two < s2 hashcode > 84524 
< s1 value > Three < s1 hashcode > 80786814 
after insert 
< s1 value > Three < s1 hashcode > 80786814 //printing three for s1 
< s2 value > Three < s2 hashcode > 80786814 //printing three for s2 
+0

请参考[为什么map使用equals方法检查键](http://stackoverflow.com/questions/31860486/does-a-map-using-equals-method-for-key-checking-exists) –

回答

3

在你的第一个片段,你equals方法总是返回false,这意味着HashMap考虑所有Student情况下是唯一的。因此s.get(s1)s.get(s2)返回不同的值。

在你的第二个片段,你equals方法总是返回true和你hashCode总是返回-1,这意味着HashMap考虑所有Student实例是相同的。因此,s.get(s1)s.get(s2)都返回相同的值(每次调用put都会覆盖先前的值)。值为“三”,因为这是您放入地图的最后一个值(通过调用s.put(s1, "Three");)。

P.S.,印刷s.get(s1).hashCode()似乎毫无意义,因为它是决定了该条目将被存储在HashMap,而不是价值hashCode桶的关键(s1.hashCode())的hashCode

顺便说一句,我起初感到惊讶,你的第一个片段不返回到s.get()所有呼叫null,因为equals总是返回false,所以HashMap不应该能够找到一个keyequal给定键。然而,检查的HashMap源代码,我发现钥匙先用==相比equals之前被调用,这就是为什么HashMap可以找到你的钥匙。

+0

嗨伊兰, 我有一个怀疑,在第一个片段,当等于方法返回false。 首先,当我们都在做,s.put(S1,“一”),这将再次但是,当我们正在做s.put存储HashMap中的值(S1,“三”),这是为什么更换价值,而不是抛出异常? –

+0

根据我的理解,当我们使用s.put(s1,“Three”)时,它将对密钥执行散列并获取桶索引并将该值存储在该索引处。 现在,当我们正在做s.put(S1,“三”),它会在关键执行hasing并得到桶索引,它会比较与索引处的项键,则总是返回false平等方法被重写,每次都返回false。 所以它应该有一个条目,但有一个相同的密钥条目将违反hashmap属性,这就是为什么它应该返回一个错误。 –

相关问题