equals与hashcode分析
我们经常在面经中看到这样的问题,为什么重写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);
}
equals与hashcode分析的更多相关文章
- == 和 equals,equals 与 hashcode,HashSet 和 HashMap,HashMap 和 Hashtable
一:== 和 equals == 比较引用的地址equals 比较引用的内容 (Object 类本身除外) String obj1 = new String("xyz"); Str ...
- java中的==、equals()、hashCode()源码分析(转载)
在java编程或者面试中经常会遇到 == .equals()的比较.自己看了看源码,结合实际的编程总结一下. 1. == java中的==是比较两个对象在JVM中的地址.比较好理解.看下面的代码: ...
- java中的==、equals()、hashCode()源码分析
转载自:http://www.cnblogs.com/xudong-bupt/p/3960177.html 在Java编程或者面试中经常会遇到 == .equals()的比较.自己看了看源码,结合实际 ...
- Java String引起的常量池、String类型传参、“==”、“equals”、“hashCode”问题 细节分析
在学习javase的过程中,总是会遇到关于String的各种细节问题,而这些问题往往会出现在Java攻城狮面试中,今天想写一篇随笔,简单记录下我的一些想法.话不多说,直接进入正题. 1.String常 ...
- ArrayList_HashSet的比较及Hashcode分析
ArrayList_HashSet的比较及Hashcode分析 hashCode()方法的作用 public static void main(String[] args) { Collectio ...
- Java中的equals和hashCode方法
本文转载自:Java中的equals和hashCode方法详解 Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要 ...
- Java提高篇——equals()与hashCode()方法详解
java.lang.Object类中有两个非常重要的方法: 1 2 public boolean equals(Object obj) public int hashCode() Object类是类继 ...
- Java实战equals()与hashCode()
一.equals()方法详解 equals()方法在object类中定义如下: 代码 public boolean equals(Object obj) { return (this == obj); ...
- 关于equals和hashCode
equals()和hashCode()是Object类的两个函数,重要性可见一斑,不过我们平时使用却未必能深入理解他们.本文从java doc触发,讲到它们与哈希表的关系,再到具体的实现,就我目前掌握 ...
随机推荐
- 无线渗透--wifiphisher之wifi钓鱼获取wifi密码
本来是想试验一下暴力破解的,但是由于字典太大,跑的时间也比较长,于是使用了钓鱼的方法. 先说一下wifiphisher钓鱼获取wifi密码的原理: wifiphisher对于你在攻击中选定的wifi会 ...
- YOLO V1、V2、V3算法 精要解说
前言 之前无论是传统目标检测,还是RCNN,亦或是SPP NET,Faste Rcnn,Faster Rcnn,都是二阶段目标检测方法,即分为“定位目标区域”与“检测目标”两步,而YOLO V1,V2 ...
- CodeForces - 876B Divisiblity of Differences
题意:给定n个数,从中选取k个数,使得任意两个数之差能被m整除,若能选出k个数,则输出,否则输出“No”. 分析: 1.若k个数之差都能被m整除,那么他们两两之间相差的是m的倍数,即他们对m取余的余数 ...
- 侯捷C++学习(一)
//c++学习//标准库非常重要//要规范自己的代码complex c1(2,1);complex c2;complex* pc = new complex(0,1);string s1(" ...
- 【pwnable.tw】 alive_note
突然发现已经两个月没写过WP了,愧疚- -... 此题也算一道分数很高的题目,主要考察Shellcode的编写. 又是一道题目逻辑很简单的题. 首先提供了三个函数 查看,删除,添加 查看函数: 此函数 ...
- 结题报告:luogu P2014
题目链接:P2014 选课 简单的树形\(dp\),借助\(dfs\)实现. 一般的树形\(dp\)数组是需要二维的,其中一维记录节点(编号或父/子节点的状态(有时三维)),另一维记录权值或计数. 重 ...
- java虚拟机05(Java虚拟机的参数)
原文在此 (1)-Xms20M 表示设置堆容量的最小值为20M,必须以M为单位 (2)-Xmx20M 表示设置堆容量的最大值为20M,必须以M为单位.将-Xmx和-Xms设置为一样可以避免堆自动扩展. ...
- 003、Java的单行注释
代码如下: package TIANPAN; public class TestDemo { public static void main(String args[]) { // JAVA的单行注释 ...
- face_recognition实时人脸识别
具体安装移步:https://www.cnblogs.com/ckAng/p/10981025.html 更多操作移步:https://github.com/ageitgey/face_recogni ...
- yum对于包和软件的安装、升级和卸载总结
在Centos下yum的安装.升级和卸载 一.使用yum安装和卸载软件,有个前提是yum安装的软件包都是rpm格式的.安装的命令是,yum install ~,yum会查询数据库,有无这一软件包,如果 ...