Qingquan-Li / blog

My Blog
https://Qingquan-Li.github.io/blog/
132 stars 16 forks source link

Java集合框架_hashCode() & equals() #35

Open Qingquan-Li opened 7 years ago

Qingquan-Li commented 7 years ago

参考: http://tutorials.jenkov.com/java-collections/hashcode-equals.html http://stackoverflow.com/questions/17027777/relationship-between-hashcode-and-equals-method-in-java

Set 是集合框架中的一个接口,结合中的对象不按特定方式排序,且没有重复对象,在使用其 add()方法将某个对象加入 Set 集合时,会采用对象的 equals() 方法比较两个对象是否相等,如果 equals() 方法比较结果为 true ,代表两个对象相等,此时,就不会再次将对象加入集合,从而保证了集合对象没有重复的。 HashSet 类为 Set 接口的实现类之一,它会按照哈希算法来存取集合中的对象,具有很好的存取和查找性能。当向一个集合中加入一个对象时,会调用该对象的 hashCode() 方法获得哈希码,根据哈希码进一步计算出对象的存放位置。因此,为了保证HashSet能正常工作,要求当两个对象用 equals() 方法比较的结果为 true 时,它们的哈希码也相等。换言之,如果某个对象的 hashCode()equals() 结果不一样,会使 HashSet 无法正常工作。如下面代码中的 Student 类。

如下代码向一个 HashCode 中加入两个 Student 对象,尽管两个对象的 equals() 方法比较结果为 true ,但是因为 Student 类并未重写 hashCode() 方法,两个对象的 hashCode() 方法比较结果并不为 true ,因此,打印结果为 2 。 可见,为了保证 HashSet 的正常工作,还需要重写 hashCode() 方法,保证与 equals() 方法结果一致。

//学生类 关键代码

public class Student {
    // 属性
    private int sid;// 学员学号
    private String name;// 姓名
    private int age;// 年龄
    private double weight;// 体重
    // 无参构造方法
    public Student() {
    }
    // 构造方法重载 :带参构造方法
    public Student(int sid, String name, int age, double weight) {
        this.sid = sid;
        this.name = name;
        this.weight = weight;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        if (age < 18 || age > 30) {
            System.out.println("***输入的年龄为:" + age + ",该年龄不合法,将重置!***");
            return;
        }
        this.age = age;
    }
    public double getWeight() {
        return weight;
    }
    public void setWeight(double weight) {
        this.weight = weight;
    }
    public int getSid() {
        return sid;
    }
    public void setSid(int sid) {
        this.sid = sid;
    }
    // 重写 equals() 方法,如果学员学号、姓名都相同,证明是同一个学生
    // instanceof 操作符用于判断一个引用类型所引用的对象是否是一个类的实例
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof Student)) {
            return false;
        }
        Student obj = (Student) o;
        if (this.sid == obj.sid && this.name.equals(obj.name)) {
            return true;
        } else {
            return false;
        }
    }
}