equals()和hashCode()使用总结

equals()
  • Object类中的equals方法和“==”是一样的,没有区别,即俩个对象的比较是比较他们的栈内存中存储的内存地址。
  • 而String类,Integer类等等一些类,是重写了equals方法,才使得equals和“==不同”,他们比较的是值是不是相等。
  • 当自己创建类时,自动继承了Object的equals方法,要想实现不同的等于比较,必须重写equals方法。
  • 我们在判断俩个对象逻辑上是否相等,即对象的内容是否相等不能直接使用继承于Object类的equals()方法,我们必须得重写equals()方法,改变这个方法默认的实现。
  • 示例
package cn.galc.test;

public class TestEquals {
public static void main(String[] args) {
/**
* 这里使用构造方法Cat()在堆内存里面new出了两只猫,
* 这两只猫的color,weight,height都是一样的,
* 但c1和c2却永远不会相等,这是因为c1和c2分别为堆内存里面两只猫的引用对象,
* 里面装着可以找到这两只猫的地址,但由于两只猫在堆内存里面存储在两个不同的空间里面,
* 所以c1和c2分别装着不同的地址,因此c1和c2永远不会相等。
*/
Cat c1 = new Cat(1, 1, 1);
Cat c2 = new Cat(1, 1, 1);
System.out.println("c1==c2的结果是:"+(c1==c2));//false
System.out.println("c1.equals(c2)的结果是:"+c1.equals(c2));//false 此时比较的内存地址
}
} //没有重写equals
class Cat {
int color, weight, height; public Cat(int color, int weight, int height) {
this.color = color;
this.weight = weight;
this.height = height;
}
}
//先判断比较对象是否为null—>判断比较对象是否为要比较类的实例—–>比较俩个成员变量是否完全相等。
public class TestEquals {
public static void main(String[] args) {
/**
* 这里使用构造方法Cat()在堆内存里面new出了两只猫,
* 这两只猫的color,weight,height都是一样的,
* 但c1和c2却永远不会相等,这是因为c1和c2分别为堆内存里面两只猫的引用对象,
* 里面装着可以找到这两只猫的地址,但由于两只猫在堆内存里面存储在两个不同的空间里面,
* 所以c1和c2分别装着不同的地址,因此c1和c2永远不会相等。
*/
Cat c1 = new Cat(1, 1, 1);
Cat c2 = new Cat(1, 1, 1);
System.out.println("c1==c2的结果是:"+(c1==c2));//false
System.out.println("c1.equals(c2)的结果是:"+c1.equals(c2));//false 此时比较的内存地址
}
}
//重写equals class Cat {
int color, weight, height; public Cat(int color, int weight, int height) {
this.color = color;
this.weight = weight;
this.height = height;
} /**
* 这里是重写相等从Object类继承下来的equals()方法,改变这个方法默认的实现,
* 通过我们自己定义的实现来判断决定两个对象在逻辑上是否相等。
* 这里我们定义如果两只猫的color,weight,height都相同,
* 那么我们就认为这两只猫在逻辑上是一模一样的,即这两只猫是“相等”的。
*/
public boolean equals(Object obj){
if (obj==null){
return false;
}
else{
/**
* instanceof是对象运算符。
* 对象运算符用来测定一个对象是否属于某个指定类或指定的子类的实例。
* 如果左边的对象是右边的类创建的对象,则运算结果为true,否则为false。
*/
if (obj instanceof Cat){
Cat c = (Cat)obj;
if (c.color==this.color && c.weight==this.weight && c.height==this.height){
return true;
}
}
}
return false;
}
}
HashCode
  • map的数据结构是数组+链表的结构(jdk1.8是数组+链表+红黑树),hashcode用来定位数组下标索引,找到对象存放的桶,然后遍历桶内链表、树,找到对应的元素。
  • Object默认的hashcode实现对于不同的对象会返回不同的值,因为是根据内存来得到的hashcode,因此,在上面那个例子中,不同的对象(即使同一个类型)有着不同的hashcode;
  • 相等的两个对象他们的hashCode()肯定相等,也就是用equal()对比是绝对可靠的
  • hashCode()相等的两个对象他们的equal()不一定相等,也就是hashCode()不是绝对可靠的。
  • 在set存储的是不重复的对象,而判断对象是否相等是调用的hashCode和equals进行判断的,所以,如果要判断两个对象逻辑上的不相等,那就必须重写这两个方法。
  • 所以在向set中添加对象时,必须重新这两个方法,且一般情况下,这两个方法要一起重写。
blic class ConflictHashCodeTest2{

     public static void main(String[] args) {
// 新建Person对象,
Person p1 = new Person("eee", 100);
Person p2 = new Person("eee", 100);
Person p3 = new Person("aaa", 200);
Person p4 = new Person("EEE", 100); // 新建HashSet对象
HashSet set = new HashSet();
set.add(p1);
set.add(p2);
set.add(p3); // 比较p1 和 p2, 并打印它们的hashCode()
System.out.printf("p1.equals(p2) : %s; p1(%d) p2(%d)\n", p1.equals(p2), p1.hashCode(), p2.hashCode());
// 比较p1 和 p4, 并打印它们的hashCode()
System.out.printf("p1.equals(p4) : %s; p1(%d) p4(%d)\n", p1.equals(p4), p1.hashCode(), p4.hashCode());
// 打印set
System.out.printf("set:%s\n", set);
} /**
* @desc Person类。
*/
private static class Person {
int age;
String name; public Person(String name, int age) {
this.name = name;
this.age = age;
} public String toString() {
return name + " - " +age;
} /**
* @desc重写hashCode
*/
@Override
public int hashCode(){
int nameHash = name.toUpperCase().hashCode();
return nameHash ^ age;
} /**
* @desc 覆盖equals方法
*/
@Override
public boolean equals(Object obj){
if(obj == null){
return false;
} //如果是同一个对象返回true,反之返回false
if(this == obj){
return true;
} //判断是否类型相同
if(this.getClass() != obj.getClass()){
return false;
} Person person = (Person)obj;
return name.equals(person.name) && age==person.age;
}
}
}

equals()和hashCode()使用总结的更多相关文章

  1. How to implement equals() and hashCode() methods in Java[reproduced]

    Part I:equals() (javadoc) must define an equivalence relation (it must be reflexive, symmetric, and ...

  2. JAVA中用堆和栈的概念来理解equals() "=="和hashcode()

    在学习java基本数据类型和复杂数据类型的时候,特别是equals()"=="和hashcode()部分时,不是很懂,也停留了很长时间,最后终于有点眉目了. 要理解equals() ...

  3. 关于equals、hashcode和集合类的小结

    一.首先明确一点:equals()方法和hashcode()方法是Object类里的方法. 查看源码可以知道,在Object类中equals(obj)方法直接返回的是  this == obj 的值. ...

  4. Object方法equals、hashCode

    java知识背景: 1)hashCode()方法返回的是Jvm的32位地址 2)==比较的是对象在jvm中的地址 3)Object的equals()比较的就是jvm物理地址 4)比较2个对象使用equ ...

  5. Java中的equals和hashCode方法

    本文转载自:Java中的equals和hashCode方法详解 Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要 ...

  6. Java提高篇——equals()与hashCode()方法详解

    java.lang.Object类中有两个非常重要的方法: 1 2 public boolean equals(Object obj) public int hashCode() Object类是类继 ...

  7. Java中==、equals、hashcode的区别与重写equals以及hashcode方法实例(转)

    Java中==.equals.hashcode的区别与重写equals以及hashcode方法实例  原文地址:http://www.cnblogs.com/luankun0214/p/4421770 ...

  8. java中equals和hashCode方法的解析

    解析Java对象的equals()和hashCode()的使用 前言 在Java语言中,equals()和hashCode()两个函数的使用是紧密配合的,你要是自己设计其中一个,就要设计另外一个.在多 ...

  9. Java实战equals()与hashCode()

    一.equals()方法详解 equals()方法在object类中定义如下: 代码 public boolean equals(Object obj) { return (this == obj); ...

  10. 一次性搞清楚equals和hashCode

    前言 在程序设计中,有很多的“公约”,遵守约定去实现你的代码,会让你避开很多坑,这些公约是前人总结出来的设计规范. Object类是Java中的万类之祖,其中,equals和hashCode是2个非常 ...

随机推荐

  1. Linux: 在某个路径及其子目录下查找所有包含“hello abcserver”字符串的文件。

    find /etc -name “*” | xargs grep “hello abcserver” 在 / 及其子目录下查找所有包含UNEXPECTED_SCHEMA find /  -name * ...

  2. 聊聊多线程哪一些事儿(task)之 一

    多线程,一个多么熟悉的词汇,作为一名程序员,我相信无论是从事什么开发语言,都能够轻轻松松说出几种实现多线程的方式,并且在实际工作种也一定用到过多线程,比如:定时器.异步作业等等,如果你说你没有用过多线 ...

  3. Visio模具与模版

    yy 这些形状就是模具 点击更多形状 然后新建模具 也可以打开已有的模具 模具名字右边有星号 代表模具未保存 鼠标右键单击可以选择保存 选择属性可以进行设置(信息之类的)也可以进行关闭 模具文件三种打 ...

  4. Oracle 11g静默安装

    1.检查安装包 安装依赖包 yum -y install gcc make binutils gcc-c++ compat-libstdc++-33 elfutils-libelf-devel elf ...

  5. k8s集群———单master节点2node节点

    #部署node节点 ,将kubelet-bootstrap用户绑定到系统集群角色中(颁发证书的最小权限) kubectl create clusterrolebinding kubelet-boots ...

  6. Kafka原理及应用(一)

    一. Kafka简介 (1) 消息中间件的两种实现模式 JMS (Java Message Service) 对消息的发送和接收定义了两种模式: 点对点模式:消息的生产和消费者均只有一个,消息由生产者 ...

  7. Ant Design中根据用户交互展示不同的标签

    Ant Design中根据用户交互展示不同的标签 Ant Design使用的是React框架,那么我们先看代码: <Fragment> <a onClick={() => th ...

  8. Linux环境下部署svn服务详解

    说明 环境: 操作系统:centos 8.0 IP:39.100.228.13 安装 用ROOT账号登录,在控制台执行以下命令,一直默认安装就好可以了. [root@localhost ~]#yum ...

  9. 低副瓣阵列天线综合2 matlab HFSS

    接着继续研究阵列天线设计,得到了电流幅度分布或功率分布之后,就可以进行阵列设计或馈电网络设计了,之前利用HFSS仿真过单列的串馈天线,后面会继续复习熟悉一下,本次我找了一篇硕士论文利用威尔金森功分器来 ...

  10. JAVA封装、继承、多态

    封装 1.概念: 将类的某些信息隐藏在类的内部,不允许外部程序访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问. 2.好处: a.只能通过规定的方法访问数据 b.隐藏类的实例细节,方便修改和实 ...