我们经常在面经中看到这样的问题,为什么重写equals方法就一定要重写hashcode方法。本文就是分析这个问题。

<!--more-->

在阿里巴巴java开发手册中就给出了这样的规则。

【强制】关于 hashCode 和 equals 的处理,遵循如下规则: 1) 只要重写 equals,就必须重写 hashCode。 2) 因为 Set 存储的是不重复的对象,依据 hashCode 和 equals 进行判断,所以 Set 存储的对象必须重写这两个方法。 3) 如果自定义对象做为 Map 的键,那么必须重写 hashCode 和 equals。 说明:String 重写了 hashCode 和 equals 方法,所以我们可以非常愉快地使用 String 对象作为 key 来使用。

看下面的代码,有什么问题吗?

import java.util.HashMap;
import java.util.Map;

public class Five {
   
public static class Person{
String name;
int age; public Person(String name, int age) {
this.name = name;
this.age = age;
}
} public static void main(String[] args) {
       
        Map<Person, Integer> map = new HashMap<>();
        map.put(new Person("sisi", 18), 9);
        map.put(new Person("lili", 12), 2);
        map.put(new Person("lili", 12), 1);
         
         
        System.out.println(map.toString());
        System.out.println(map.get(new Person("sisi", 18)));
        System.out.println(map.get(new Person("lili", 12)));
         
}
}

运行后的结果为:

{com.chr.binarysearch.Five$Person@7852e922=1, com.chr.binarysearch.Five$Person@15db9742=9, com.chr.binarysearch.Five$Person@6d06d69c=2}
null
null

我们不难看出new Person("lili", 12)这个对象作为key,竟然加入到HashMap中两次,违背了HashMap中key是唯一的原则。我们可以插入System.out.println(new Person("lili", 12).hashcode());来获得两次添加到HashMap中对象的hashcode的值。

2018699554
118352462

虽然对象相同,但是hashcode值不同,这也解释了通过对象获取value值为null。

那么该如何保证自定义类对象作为key的唯一性?

重写equals方法和hashcode方法。

在java核心技术 卷1中给出了编写一个完美的equals方法的建议:

public boolean equals(Object otherObj){
  1)检测this与otherObj是否引用同一个对象:
  if(this == otherObj){
    return true;
  }
  2)检测otherObj是否为null,如果为null,返回false。
  if(otherObj == null){
  return false;
  }
  3)比较this与otherObj是否属于同一个类。
  if(getClass() != otherObj.getClass()){
  return false;
  }
  4)将otherObj转换成相应的类型变量:
  ClassName other = (ClassName)otherObj;
  5)开始对所有需要比较的域进行比较。使用==比较基本类型域,使用equals比较对象域。
  return field1 == other.field1
      && Objects.equals(field2, other.field2);
}

这是我自己重写的equals方法

public boolean equals(Object otherObj) {
if(this == otherObj) {
return true;
}
          if(otherObj == null) {
          return false;
          }
           
          if(!(otherObj instanceof Person)) {
          return false;
          }
           
          Person other = (Person)otherObj;
return Objects.equals(name, other.name) && age == other.age;
}
}

之所以用objects.equals(name,other.name);防止空指针异常。

重写hashcode方法

public int hashCode() {
return Objects.hash(name,age);
}

最新文章

  1. [k]自定义样式下拉菜单
  2. linux top 参数详解
  3. iOS证书失效
  4. 【wikioi】2800 送外卖(状压dp+floyd)
  5. centos下安装图像化界面
  6. RESTful WebService入门
  7. hdu 5445 Food Problem 多重背包
  8. C#_Ajax_分页
  9. Hibernate中inverse属性与cascade属性
  10. git+Coding.netの小试牛刀
  11. Chapter 4. Button, Checkbutton, and Radiobutton Widgets 按钮,复选按钮,单选按钮
  12. CSS3 模拟笑脸
  13. liunx清理磁盘du -h --max-depth=1 /data/*
  14. ●杜教筛入门(BZOJ 3944 Sum)
  15. JavaScript 执行机制
  16. 【Tomcat】Tomcat工作原理及简单模拟实现
  17. JDK 在 Linux 上安装的详细过程
  18. jquery获取包含本身的元素
  19. DispatcherServlet源码注解分析
  20. 如何创建XHTML表单

热门文章

  1. tensorflow实现线性模型和sklearn的线性模型比较
  2. 无需重新编译安装PHP扩展的方法
  3. SQL statement ignored
  4. Java常考面试题(二)(转)
  5. NOIp2018普及组初赛试卷
  6. 怎样设置使IntelliJ IDEA智能提示忽略大小写?
  7. 使用线程池测试cpu的并发计算能力
  8. 留学生Essay写作清晰简洁8大原则
  9. ApplicationListener监听使用ContextRefreshedEvent事件类型会触发多次
  10. Gym 101158D(暴力)