标签:lang close rgb person hash public 插入 name boolean
在学习hashCode()时候看到了几句不理解的话,现在终于搞懂了。
参考文章:https://www.cnblogs.com/skywang12345/p/3324958.html
因为修改了判断相等的逻辑,就要同步修改计算hashCode的逻辑。
举个例子,Person类,只重写equals:name和age相同即为相等。现有两个对象p1、p2,通过equals判断他们相同,但是同原始的hashCode逻辑看,他们是两个不同的对象有不同的hashCode,就能插入HashSet。
再重写hashCode(),使hashcode的计算逻辑用上name和age,这样就插不进去了,因为相同的name和age算出来了相同的hashCode,HashSet认为他们相等。
只覆盖equals():
import java.util.*; import java.lang.Comparable; /** * @desc 比较equals() 返回true 以及 返回false时, hashCode()的值。 * * @author skywang * @emai kuiwu-wang@163.com */ public class ConflictHashCodeTest1{ public static void main(String[] args) { // 新建Person对象, Person p1 = new Person("eee", 100); Person p2 = new Person("eee", 100); Person p3 = new Person("aaa", 200); // 新建HashSet对象 HashSet set = new HashSet(); set.add(p1); set.add(p2); set.add(p3); // 比较p1 和 p2, 并打印它们的hashCode() System.out.printf("p1.equals(p2) : %s; p1(%d) p2(%d)\n", p1.equals(p2), p1.hashCode(), p2.hashCode()); // 打印set System.out.printf("set:%s\n", set); } /** * @desc Person类。 */ private static class Person { int age; String name; public Person(String name, int age) { this.name = name; this.age = age; } public String toString() { return "("+name + ", " +age+")"; } /** * @desc 覆盖equals方法 */ @Override public boolean equals(Object obj){ if(obj == null){ return false; } //如果是同一个对象返回true,反之返回false if(this == obj){ return true; } //判断是否类型相同 if(this.getClass() != obj.getClass()){ return false; } Person person = (Person)obj; return name.equals(person.name) && age==person.age; } } }
结果:p1.equals(p2) : true; p1(1169863946) p2(1690552137) set:[(eee, 100), (eee, 100), (aaa, 200)]
同时覆盖了equals()和hashCode():
运行结果:
p1.equals(p2) : true; p1(68545) p2(68545)
p1.equals(p4) : false; p1(68545) p4(68545)
set:[aaa - 200, eee - 100]
equals()和hashCode()是同时重写的,相等的对象一定能计算出来相等的hashcode。
有一些巧合,会使计算出来的hashcode相等,但属性不同。
标签:lang close rgb person hash public 插入 name boolean
原文地址:https://www.cnblogs.com/yunqijinglan/p/14899954.html