Java 中的 equals 与 hashCode。
- 如果两个对象的 equals 方法相等,则他们的 hashCode 值一定相同。
- 如果两个对象的 hashCode 值相同,则他们的 equals 方法不一定相等。
- 如果两个对象的 hashCode 值不相同,则他们的 equals 方法一定不相等。
equals 相等是 hashCode 值相等的充分不必要条件。
- 上述的原则不可以违背,否则在使用容器时相同的对象可以出现在 Set 集合中,同时增加新元素的效率会大大下降。
两个对象的 hashCode 值相同,则他们的 equals 方法不一定相等。
由于 hashCode() 方法的由来是根据这个对象内存储的数据以及对象的一些特征来做散列并返回一个有符号的32位哈希值
,所以 hashCode() 方法返回的是一个散列值,而对于一个散列来说不同的内容也可能会出现相同的散列值,所以即使两个对象的 hashCode() 返回值一样,也并不能代表两个对象的值相等,要判断两个对象是否相等还是需要使用 equals() 方法。
Java 中 equals() 和 hashCode() 的作用。
1、== 双等于号
- 如果作用于基本数据类型的变量,则直接比较其存储的值是否相等(
基本比内容
)。 - 如果作用于引用类型的变量,则比较的是所指向的对象的地址(
引用比地址
)。
2、equals() 方法
注意:1. equals() 方法不能作用于基本数据类型的变量。
2. Java 中对象默认的 equals() 方法 实现的是 == 比较。
- 如果没有对 equals 方法进行重写,则比较的是引用类型的变量所指向的对象的地址(
与 == 用法相同
); - 包装类型 :String、Date等类对 equals() 方法进行了重写的话,比较的是所指向的对象的内容。
3、hashCode() 方法
- hashCode() 方法的主要作用是为了配合基于散列的集合一起正常运行,这样的散列集合包括 HashSet、HashMap 以及 HashTable 。
- hashCode() 的作用是为了提高在散列结构存储中查找的效率,在线性表中没有作用。
eg:当向集合中插入对象时,如何判别在集合中是否已经存在该对象。
当少量数据的时候,我们可采用 equals() 方法进行这个比较,但是,如果集合中已经存在数万条数据,再采用 equals() 方法进行逐一比较,会大大减低效率。由此引入了 hashCode() 方法。
集合要添加新的对象时,先去调用这个对象的 hashCode() 方法,得到对应的 hashcode 值,实际上在 HashMap 的具体实现中会用一个 table 保存已经存进去的对象的 hashcode 值,
如果 table 中没有该 hashcode 值,它就可以直接存进去,不用再进行任何比较了;如果存在该hashcode值, 就调用它的 equals() 方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址进行保存,这样一来实际调用 equals() 方法的次数就大大降低了。
Java 中 重写 equals() 方法。
1、重写 equals() 方法时,重写 hashCode() 方法。
- 新建一个实体类。
- 使用 eclipse 【Alt + Shift +S】/ IDEA 【Alt + Insert 】,新建 getters & setters 方法,新建 equals() & hashCode() 方法。
- 得到的结果如下(此处省略了 getters & setters) :
系统生成好的属于通用的模板,我们可以根据自己的需求生成自己需要的。
2、重写 equals() 方法,为什么要重写 hashCode() 方法?
- 即重写 equals() 方法,又重写 hashCode() 方法。
- 仅仅重写 equals() 方法,没有重写 hashCode() 方法。
综上所述:1、equals() 相等,但是 hashCode() 不相等,不符合文章一开始强调的equals() 相等,则 hashCode() 也要相等。
2、为了保证同一个对象,保证在 equals() 相同的情况下 hashcode() 值必定相同,建议两个都要重写