二、==和equals()的区别
三、为什么重写了equals方法时,都要进而重写Hashcode方法呢?
原因如下:当equals此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。如下:
(1)当obj1.equals(obj2)为true时,obj1.hashCode() == obj2.hashCode()必须为true
(2)当obj1.hashCode() == obj2.hashCode()为false时,obj1.equals(obj2)必须为false
hashcode是用于散列数据的快速存取,如利用HashSet/HashMap/Hashtable类来存储数据时,都是根据存储对象的hashcode值来进行判断是否相同的。
这样如果我们对一个对象重写了euqals,意思是只要对象的成员变量值都相等那么euqals就等于true,但不重写hashcode,那么我们再new一个新的对象,当原对象.equals(新对象)等于true时,两者的hashcode却是不一样的,由此将产生了理解的不一致。
四、如何重写equals()方法?
package com.study; import java.util.Date; import java.util.Objects; public class Employee { private String name; private double salary; private Date hireDay; public Employee(String name, double salary, Date hireDay) { this.name = name; this.salary = salary; this.hireDay = hireDay; } public Employee() { } /** * 重写equals()方法 * * @param obj * @return */ @Override public boolean equals(Object obj) { // 如果为同一对象的不同引用,则相同 if (this == obj) { return true; } // 如果传入的对象为空,则返回false if (obj == null) { return false; } // 如果两者属于不同的类型,不能相等 if (getClass() != obj.getClass()) { return false; } // 类型相同, 比较内容是否相同 Employee other = (Employee) obj; return Objects.equals(name, other.name) && salary == other.salary && Objects.equals(hireDay, other.hireDay); } } /** * 测试类 */ class Test { public static void main(String[] args) { Date date = new Date(); Employee e1 = new Employee("zhangsan", 100, date); Employee e2 = new Employee("zhangsan", 100, date); System.out.println(e1.equals(e2)); } }
五、重写hashCode()方法
1、推荐阅读
2、如何重写hashcode方法;
3、这边再拷贝下别人说的比较经典的总结:
Google首席Java架构师Joshua Bloch在他的著作《Effective Java》中提出了一种简单通用的hashCode算法
1. 初始化一个整形变量,为此变量赋予一个非零的常数值,比如int result = 17;
2. 选取equals方法中用于比较的所有域,然后针对每个域的属性进行计算:
(1) 如果是boolean值,则计算f ? 1:0
(2) 如果是byte\char\short\int,则计算(int)f
(3) 如果是long值,则计算(int)(f ^ (f >>> 32))
(4) 如果是float值,则计算Float.floatToIntBits(f)
(5) 如果是double值,则计算Double.doubleToLongBits(f),然后返回的结果是long,再用规则(3)去处理long,得到int
(6)如果是对象应用,如果equals方法中采取递归调用的比较方式,那么hashCode中同样采取递归调用hashCode的方式。 否则需要为这个域计算一个范式,比如当这个域的值为null的时候,那么hashCode值为0
(7)如果是数组,那么需要为每个元素当做单独的域来处理。如果你使用的是1.5及以上版本的JDK,那么没必要自己去 重新遍历一遍数组,java.util.Arrays.hashCode方法包含了8种基本类型数组和引用数组的hashCode计算,算法同上,
4、关于hashcode,我们一定要知道一个口诀:
Java核心(六):==和equals()的区别;重写equals()方法
原文:https://www.cnblogs.com/newbie27/p/10426846.html