Java基础 - 关于 equals()、hashcode() 重写

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010289802/article/details/81180364

Java 中重写 equals() 方法同时要重写 hashcode() 方法

equals()

Object对象中的 public boolean equals(Object obj),对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true

注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。如下:

  1. 当 obj1.equals(obj2) 为 true 时,obj1.hashCode() == obj2.hashCode() 必须为 true
  2. 当 obj1.hashCode() == obj2.hashCode() 为 false 时,obj1.equals(obj2) 必须为 false

如果不重写equals,那么比较的将是对象的引用是否指向同一块内存地址,重写之后目的是为了比较两个对象的value值是否相等。

特别指出利用equals比较八大包装对象(如int,float等)和String类(因为该类已重写了equals和hashcode方法)对象时,默认比较的是值,在比较其它自定义对象时都是比较的引用地址

hashcode()

hashcode 是用于散列数据的快速存取,如利用 HashSet、HashMap、Hashtable 类来存储数据时,都是根据存储对象的 hashcode 值来进行判断是否相同的。

如果我们对一个对象重写了 euqals ,意思是只要对象的成员变量值都相等那么 euqals 就等于 true ,但不重写hashcode ,那么我们再 new 一个新的对象,当原对象.equals(新对象)等于true时,两者的 hashcode 却是不一样的,由此将产生了理解的不一致,如在存储散列集合时(如Set类),将会存储了两个值一样的对象,导致混淆,因此,就也需要重写hashcode()

举个栗子:

public class Test {
    public static void main(String[] args) {
        User u1 = new User("1", "zhangsan");
        User u2 = new User("2", "zhangsan");
        System.out.println("u1.equals(u2) = " + u1.equals(u2));
        System.out.println("u1.hashcode = " + u1.hashCode());
        System.out.println("u2.hashcode = " + u2.hashCode());

        HashMap<User, User> hashMap = new HashMap<>();
        hashMap.put(u1, u1);
        hashMap.put(u2, u2);
        System.out.println("hashmap.size = " + hashMap.size());
    }
}

class User {
    private String id;
    private String name;

    public User(String id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof User) {
            User user = (User) obj;
            return name.equals(user.name);
        }
        return super.equals(obj);
    }

    @Override
    public int hashCode() {
        return name.hashCode();
    }
}

代码中重写了 hashCode()方法。输出如下:

若不重写 hashCode() 方法,则输出:

猜你喜欢

转载自blog.csdn.net/u010289802/article/details/81180364