在java中,所有的对象都是继承于Object类。Ojbect类中有两个方法equals、hashCode,这两个方法都是用来比较两个对象是否相等的。

在未重写equals方法我们是继承了object的equals方法,那里的 equals是比较两个对象的内存地址,显然我们new了2个对象内存地址肯定不一样

  • 对于值对象,==比较的是两个对象的值
  • 对于引用对象,比较的是两个对象的地址

Object 默认的equals方法同==,一般来说我们的对象都是引用对象,要重写equals方法。

     public boolean equals(Object obj) {
return (this == obj);
}
     public static void main(String[] args) {
Object c=new Object();
Object d=new Object();
System.out.println(c.equals(d));//false }

这个比较下,结果是false,也就是这两个对象不一样,但是有些业务,我们需要证明一个类的下面的实例对象时相等的,这时候我们就必须重写equlas方法了。

如下代码,我们新建一个对象Student,并重写equals与hashCode方法

 public class Student {

     private int no;

     private String name;

     @Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; if (no != student.no) return false;
return !(name != null ? !name.equals(student.name) : student.name != null); } @Override
public int hashCode() {
int result = no;
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
} public int getNo() {
return no;
} public void setNo(int no) {
this.no = no;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}
         Student a=new Student();
Student b=new Student();
System.out.println(a.equals(b));//ture

此时可以看出a、b对象相等.

hashCode方法也是可以用来比较两个对象是否相等的。但是我们很少使用,应该说是很少直接使用。hashCode方法返回的是一个int值,可以看做是一个对象的唯一编码,如果两个对象的hashCode值相同,我们应该认为这两个对象是同一个对象。

一般如果使用java中的Map对象进行存储时,他会自动调用hashCode方法来比较两个对象是否相等。

所以如果我们对equals方法进行了重写,建议一定要对hashCode方法重写,以保证相同的对象返回相同的hash值,不同的对象返回不同的hash值。

1、重写equals方法时需要重写hashCode方法,主要是针对Map、Set等集合类型的使用;

a: Map、Set等集合类型存放的对象必须是唯一的;

b: 集合类判断两个对象是否相等,是先判断equals是否相等,如果equals返回TRUE,还要再判断HashCode返回值是否ture,只有两者都返回ture,才认为该两个对象是相等的。

2、由于Object的hashCode返回的是对象的hash值,所以即使equals返回TRUE,集合也可能判定两个对象不等,所以必须重写hashCode方法,以保证当equals返回TRUE时,hashCode也返回Ture,这样才能使得集合中存放的对象唯一。

个人感觉equals重写,是站在使用的角度上考虑的:类设计者不希望通过内存地址来比较两个对象是否相等,重写这个equals方法,能够方便的使用Collection<E>操作自定义对象E(Collection中很多方法涉及E.equals()的);而hashCode的重新,是方便Map<K,V>的使用,良好的自定义hashCode,会极大的提高Map的使用效率。

为啥说equals重新时,一定要重写hashCode?感觉这么理解不知行不行:既然自定义类重写了equals方法,说明类设计者不希望通过内存地址来比较两个对象是否相等了。而Object的hashCode也是对象的内存地址,既然不希望通过地址比较对象,那么以内存地址作为hashCode也就没有实际使用意义了,索性将自定义对象的hashCode方法也重写了吧!

参考: hashCode的作用   重写equals方法为什么要重写hashCode方法

为什么要重写equals()方法与hashCode()方法的更多相关文章

  1. JAVA正确地自定义比较对象---如何重写equals方法和hashCode方法

    在实际应用中经常会比较两个对象是否相等,比如下面的Address类,它有两个属性:String province 和 String city. public class Address { priva ...

  2. HashSet中存方用户自己定义数据类型数据,重写equals方法和hashCode方法

    import java.util.Set; import java.util.HashSet; public class SetTest { public static void main(Strin ...

  3. Hibernate中为什么要重写equals方法和hashcode方法

    1.*为什么要重写equals方法,首先我们来看一下equals源码: public boolean equals(Object anObject) { if (this == anObject) { ...

  4. 对象作为 map 的 key 时,需要重写 equals 方法和 hashCode 方法

    对象作为 map 的 key 时,需要重写 hashCode 和 equals方法 如果没有重写 hashCode 方法,那么下面的代码示例会输出 null 我们首先定义一个对象:BmapPoint, ...

  5. Java重写equals方法和hashCode方法

    package com.ddy; public class User {     private Integer id;     private String name;     private St ...

  6. HashSet中的元素必须重写equals方法和hashCode方法

    http://jingyan.baidu.com/article/d5a880eb8fb61d13f147cc99.html 1.为什么必须重写这两个方法. 2.什么事hashSet去重,符合什么样的 ...

  7. JAVA中equals方法与hashCode方法学习

    首先参考文章:http://www.oschina.net/translate/working-with-hashcode-and-equals-methods-in-java 1,equals方法的 ...

  8. 关于Object类的equals方法和hashCode方法

    关于Object类的equals的特点,对于非空引用: 1.自反性:x.equals(x) return true : 2.对称性:x.equals(y)为true,那么y.equals(x)也为tr ...

  9. java中equals方法和hashcode方法的区别和联系,以及为什么要重写这两个方法,不重写会怎样

    一.在Object类中的定义为:public native int hashCode();是一个本地方法,返回的对象的地址值.但是,同样的思路,在String等封装类中对此方法进行了重写.方法调用得到 ...

  10. Java 如何重写对象的 equals 方法和 hashCode 方法

    前言:Java 对象如果要比较是否相等,则需要重写 equals 方法,同时重写 hashCode 方法,而且 hashCode 方法里面使用质数 31.接下来看看各种为什么. 一.需求: 对比两个对 ...

随机推荐

  1. 【HTTPS】Https和SSL学习笔记(二)

    此文讲述证书的相关信息,参考文章链接http://www.guokr.com/post/116169/ 一. 证书的类型 常用的几种证书如下: (1) SSL证书,用于加密HTTP (2) 代码签名证 ...

  2. 输出一个等边三角形的字母阵,等边三角形的两腰为字母A,往里靠依次字母大一个(详细题目文章中描述)

    题目简单的描述就是输出这么一个金字塔型的字母阵(等边三角形) /* A ABA ABCBA */ /* //解法①:对称轴法 #import <stdio.h> int main() { ...

  3. (转).Net平台开源作业调度框架Quartz.Net

    Quartz.NET介绍: Quartz.NET是一个开源的作业调度框架,是OpenSymphony 的 Quartz API的.NET移植,它用C#写成,可用于winform和asp.net应用中. ...

  4. 阿里云 CentOS 安装JDK

    初用阿里云,使用centOS linux64操作系统 . 自己上传jdk文件总是安装失败,原因估计是因为我的网络不好,导致文件损坏. 解决办法,直接在linux命令行模式下,到官网下载 jdk,命令如 ...

  5. 最近用到的Linux常用命令总结

    最近用到的Linux常用命令总结 - ls :显示当前目录文件信息 `ls -a -l` - cd :目录跳转 cd .. 上级目录 cd ~ home目录 cd - 最近目录 - cat :在屏幕上 ...

  6. jQuery去掉导航分割线的最后一条竖线

    #top #navigation ul li { float:left; width:120px; background:url(../images/navline.jpg) no-repeat 11 ...

  7. sublime主题推荐

    PS:之前在CSDN上写的文章,现在转到博客园~ 寒假的时候发现一个sublime主题,我觉得很赞哦~~推荐给大家~~ 下载方式 step1:ctrl+shift+p  调出command palet ...

  8. start-stop-daemon 命令

    Usage: start-stop-daemon [<option> ...] <command> Commands: -S|–start — <argument> ...

  9. Visual C++ 对话框增加菜单栏

    1.添加菜单资源     在resourceview视图中右击选择insert,添加一个菜单资源IDR_MENU1,同时设定好响应的菜单项,例 如:         菜单1               ...

  10. oracle expdp 无法导出SYS下特定TABLE

    创建测试表: D:\app\product\\db_1>sqlplus "/as sysdba" SQL :: Copyright (c) , , Oracle. All r ...