1、为什么要重写equals方法 和 hashCode 方法?
因为在Object中的equals 方法返回的是对象的地址值做比较的结果,而重写之后会根据对象的内容去做比较。
那么对于hashCode方法,Object 中是这样写的 public native int hashCode(); 在这里hashcode是本地方法,java的内存是安全的,因此无法根据散列码得到对象的内存地址,但实际上,hashcode是根据对象的内存地址经哈希算法得来的,所以我们需要重写hashCode方法。
2、Java中两个对象值相同,哈希值一定相同吗?
两个对象值相同(x.equals(y) == true),则一定有相同的hashcode。
两个对象相等,hashcode一定相等
两个对象不等,hashcode不一定不等
hashcode相等,两个对象不一定相等
hashcode不等,两个对象一定不等
3、为什么要重写toString() 方法?
如果是基本数据类型,我们不需要重写toString() 因为基本数据类型,在Object 中的toString() 方法是显示对象内容,而不是对象地址。
而引用数据类型中,toString() 方法显示的是对象的地址值,而不是对象内容,所以引用类型中需要通过重写此方法来看对象内容。
4、对象内容一样,哈希值一定一样吗?(只有重写hashCode() 方法后才一样 )
例如:
HashSet<Person> set = new HashSet<>();
Person p1 = new Person("AAA",18);
Person p2 = new Person("AAA",18);
Person p3 = new Person("AAA",19);
System.out.println(p1.hashCode());
System.out.println(p2.hashCode());
System.out.println(p1 == p2);
System.out.println(p1.equals(p2));
set.add(p1);
set.add(p2);
set.add(p3);
System.out.println(set);
如上,得出的结果如下:
1967205423
42121758
false
false
[Person{name='AAA', age = 18},Person{name='AAA', age = 18},Person{name='AAA', age = 18}]
如上可以看到,前面两个对象内容都一样,但是都被存了下来,为什么呢?那就是因为只重写了toString()方法,但是没有重写hashCode() 方法。
那么
如果你重写了equals方法 和hashCode() 方法,你就会发现
734175839
734175839
false
true
[Person{name='AAA', age=19}, Person{name='AAA', age=18}]