写点什么

你真的了解 equals 方法吗?

用户头像
若尘
关注
发布于: 2021 年 06 月 15 日
你真的了解 equals 方法吗?

equals() & hashCode()

i. 首先,简单介绍一下具体用法



  • boolean equals(Object obj) - 用于判断调用对象是否与参数对象相等


  • 若希望比较对象的内容,则需要进行方法的重写

  • 若该方法重写了,则应该去重写 hashCode()方法,以维护 hashCode 方法的常规协定

  • int hashCode() - 用于获取调用对象的哈希码值(内存地址和编号)并返回

  • 若两个对象调用 equals()方法相等,则各自调用该方法得到的哈希码值必须相同

  • 若两个对象调用 equals()方法不相等,则各自调用该方法的结果可以相同,但是最好不相同

ii. 一个案例带你搞懂 equals() 和 hashCode()

  • 首先,我们创建一个 Student 类


// Student类封装public class Student {
private int id; private String name; public Student() { super(); }
public Student(int id, String name) { super(); this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { if (id > 0) { this.id = id; } else { System.out.println("学号不合理!"); } } public String getName() { return name; } public void setName(String name) { this.name = name; }
复制代码


  • 在 TestStudent 类中进行测试


public class TestStudent {
public static void main(String[] args) { Student s1 = new Student(1001, "老王"); Student s2 = new Student(1001, "老王"); System.out.println(s1 + " " + s2); // 调用equals方法来判断两个对象是否相同,这里默认从Object类中继承 boolean b1 = s1.equals(s2); System.out.println("b1 = "+b1); // b1 = false System.out.println(s1 == s2); // false }
}
复制代码


Euqals.Student@2f92e0f4 Euqals.Student@28a418fcb1 = falsefalse
复制代码


  • 显然,因为 equals 方法默认比较的是地址,这里 s1 与 s2 地址不同,输出为 false。那么,如果我们想要另两个对象学号相同时,使用 equals 方法时输出为 true 应该怎么做呢,很显然,equals 方法是属于 Object 类的,那么我们只要在 Student 类中对其进行重写即可


// Student类封装public class Student {
private int id; private String name; public Student() { super(); }
public Student(int id, String name) { super(); this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { if (id > 0) { this.id = id; } else { System.out.println("学号不合理!"); } } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public boolean equals(Object obj) { // 1. 若两个对象的地址一样,则内容一定相同 if (this == obj) { return true; } // 2. 若调用对象不为空, 参数对象为空,则内容一定不相同 (如t1.equals(null)) else if (obj == null) { return false; } // 3. 若参数对象和调用对象类型一致,则由学号来决定两个对象内容是否相同 else if (obj instanceof Student) { Student s = (Student)obj; if (this.getId() == s.getId()) { return true; } else { return false; } } // 4. 若参数对象和调用对象类型不一致,则内容一定不相同 else { return false; } }
复制代码


  • 这里,我们对 4 中情况进行了考虑,我们再次运行 TestStudent 代码,发现此时输入了 true,因为当我们重写 equals 方法后,则调用子类重写以后的版本,比较内容。

  • 在这里,我们会想到 String 类,那么我们对 String 对象调用 equals 方法会输出什么呢?


System.out.println("你好".equals("你好"));  // true
复制代码


true
复制代码


  • 这里输出的是 true,我们知道这是两个 String 对象,输出不应该是 false 吗?根据前面所讲的,我们明白了,原来 , 那么我们就明白了。到这里就完了吗?不,还没有,前面我们说过,一般为了维护 hashCode 方法的常规协定,我们要在 Student 类中重写 hashCode 方法


  // 为了保证和equals方法结果一致性,需要重写hashCode  @Override  public int hashCode() {        // return getId();        // 随便定义,为了保持ID相同    // 维护hashCode方法的常规协定    int type = 12;    return type*31 + getId();  }
复制代码


  • 我们在 TestStudent 类中进行测试


    // 调用从Object类中继承的hashCode方法来获取对应的哈希码    // 当Student类中重写hashCode方法后,则调用重写以后的版本    int res = s1.hashCode();    System.out.println("res = " + res);        res = s2.hashCode();    System.out.println("res = " + res);
复制代码


res = 1373res = 1373
复制代码


  • 这里就达到了我们想要的结果,你 Get 到了吗?


喜欢就关注博主吧,你的关注点赞是对博主最大的鼓励!:smile:

发布于: 2021 年 06 月 15 日阅读数: 9
用户头像

若尘

关注

还未添加个人签名 2021.01.11 加入

还未添加个人简介

评论

发布
暂无评论
你真的了解 equals 方法吗?