在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. C#之装箱和拆箱

    在实际编码过程中,有时候会出现装箱和拆箱操作.下面就类分别认识一下: 需要注意的是,类型转换和这个是不同的.Convert方法并没有发生装箱和拆箱操作,而是类型转换,包括int.parse等等. 装箱 ...

  2. iOS Core Animation学习总结(2)--实现自定义图层

    一. 创建图层继承于CALayer,并在子类实现drawInContext方法 @interface CTLayer : CALayer @end @implementation CTLayer -( ...

  3. easyui-prompt弹出框操作

    效果图如下: 代码如下: $(document).ready(function () { //绑定按钮操作 $('#btnMove').click(function () { var ids = ge ...

  4. nodejs连接MySQL数据库

    在github上搜索orm2 https://github.com/dresende/node-orm2: 在项目文件夹使用npm install orm下载下来,然后书写配置文件 var orm = ...

  5. 《C#入门典》

    这本书算是我读的第一本关于.NET的书. 上大学的时候,教我们课的老师经常给我们安利"Wrox红皮书",说这是程序员写给程序员的书,有很高的参考价值. 这本书的电子版,有1000多 ...

  6. Java标准输入输出流的重定向及恢复

    在Java中输入输出数据一般(图形化界面例外)要用到标准输入输出流System.in和System.out,System.in,System.out默认指向控制台,但有时程序从文件中输入数据并将结果输 ...

  7. Centos 添加SWAP(交换分区)

    一般情况下,内存过小时,可以增加 swap,大小为内存的2倍为宜,具体设置如下: 1.进入目录cd /var/ 2.获取要增加的SWAP文件块(这里以1GB为例)dd if=/dev/zero of= ...

  8. 【转】C#.net拖拽实现获得文件路径

    C#.net拖拽实现获得文件路径 作者Attilax ,  EMAIL:1466519819@qq.com 思路: 通过DragEnter事件获得被拖入窗口的“信息”(可以是若干文件,一些文字等等), ...

  9. Cassandra1.2文档学习(7)—— 规划集群部署

    数据参考:http://www.datastax.com/documentation/cassandra/1.2/webhelp/index.html#cassandra/architecture/a ...

  10. PHP字符

    匹配查找 strstr strpos 通常用在表单验证里面可以用到 substr 正值表达式匹配 preg_mathc(), preg)mathc_all() , preg_grep() 编码格式的转 ...