参考:
为什么要重写hashcode和equals方法?你能说清楚了吗
主要是因为自定义变量在存入HashMap的时候会用到ha’shCode();
HashMap
在HashMap中如果要比较key是否相等,要同时使用这两个函数。
比较过程:
put的时候需要比较是否有相同的Key。
先求出Key的hashCode(),比较两个值是否相等,若相等再比较equals(),若相等则认为这两个Key是同一个。若hashCode()相等,但equals()不相等,则也认为他们不相等。
- 如果只重写equals(),则对于同一个实体(变量完全一样的对象),也无法获取相同的value,获得的可能是null。
- 如果只重写hashCode(),则当比较equals()时,只是看这两个变量是不是同一个对象,代表同一实体的两个对象返回的是false
因此,如果需要将自定义的变量作为HashMap的key存入,则必须重写两个函数。同时从面向对象来看,如果你希望代表同一个实体的两个对象的hashCode()也是一样的,那么也必须重写hashCode();
HashMap,比较的依据
hashCode()的规则
两个对象相等,hashCode()一定相等。
两个对象不等,hashCode()不一定不等。
hashCode()相等,两个对象不一定相同。
hashCode()不等,两个对象一定不相同。
测试例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| public class JavaEqual { public static void main(String[] args) {
out("equals与hashcode测试"); Student aStudent = new Student("me"); Student bStudent = new Student("me");
if (aStudent.equals(bStudent)) { System.out.println("aStudent == bStudent (using customed equal function)"); System.out.println("aStudent.hashcode " + aStudent.hashCode()); System.out.println("bStudent.hashcode " + bStudent.hashCode()); }
HashMap<Student, String> map = new HashMap<>(3);
map.put(aStudent, "a");
String getBstudent = map.get(bStudent);
System.out.println("using bStudent get aStudent's value:" + getBstudent); outEnd();
} public static void out(String message) { System.err.flush(); System.out.flush(); System.out.println("/*********************************\n" + " * " + message + "\n" + " *********************************/"); System.err.flush(); System.out.flush(); } public static void outEnd() { System.err.flush(); System.out.flush(); System.out.println("/**************** END **************/\n\n"); System.err.flush(); System.out.flush(); } }
|