废话不多说,先上案例,如下
先定义一个User类,并定义2个属性,构造方法,new 2个对象,user1 user2
public static void main(String[] args) { User user1 = new User(1,"张三"); User user2 = new User(1,"张三"); System.out.println(user1.hashCode()); System.out.println(user2.hashCode()); System.out.println(user1.equals(user2)); Set<User> set = new HashSet<User>(); set.add(user1); set.add(user2); System.out.println(set); }
运行程序,输出结果如下:
重写 hashcode 和 equals 重新运行,结果如下:
2张运行结果可以看出hashcode 值相等,且 equals 返回 true HashSet 起到去重效果
@Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; if (age != user.age) return false; return name.equals(user.name); } @Override public int hashCode() { int result = age; result = 31 * result + name.hashCode(); return result; }
以下是关于hashcode的一些规定:
两个对象相等,hashcode一定相等,两个对象不等,hashcode不一定不等;
hashcode相等,两个对象不一定相等,hashcode不等,两个对象一定不等;
以下是Object源码中hashcode 和 equals的具体实现
public native int hashCode(); public boolean equals(Object obj) { return (this == obj); }
不重写 hashcode 和 equals 的情况,默认使用Object内中的 equals 和hashcode方法
默认情况下Object 为不同对象生成的 hashcode 一般是不同的,默认equals 方法比较的是2个对象的内存地址,所以比较结果为false
我们只重新hashcode方法,不重新equals 方法,运行程序结果如下:
虽然hashcode值相同,但是比较的任然是内存地址,然而2个对象的内存地址是不一样的,所以比较结果任然是false,只有同时重新hashcode 和equals 才能判读2个对象是否相等,才能达到去重效果;
注意:==比较的是内存地址, equals比较的是值是否相等