关于重写对象equals方法的问题
1.==和equals的区别
a.基本数据类型使用 == 进行值的比较
b.引用类型使用 == 进行比较时,直接比较的是对象的存储地址,即两个引用是否指向了同一个对象。
c.equals方法是基类Object中的方法,该方法如果在其他类中没有被重写,则比较的还是地址,即两个引用是否指向了同一个对象,和==是一样的(其实equals方法的默认实现就是==)。该方法在一些实现类中已经被重新了,如 String和Integer等包装类,在这些类中用来比较值是否相等。
即:equals方法如果没有重写时在比较两个对象时的作用和==是一样的,都是比较两个对象是不是同一个对象。这里如果我们比较的是地址,那么最好用==,因为无论是否重写了Object的equals方法,引用类型使用==时永远比较的是地址。
2.为什么要重写equals方法?
有时候在实际使用的过程中,比如有两个对象 Address address1=new Address("甘肃”,"兰州"); Address address2=new Address("甘肃”,"兰州"); 这两个对象中的内容都是相同的,我们则认为这两个对象是相等的。但不重写equals时使用 address1.equals(address2)进行比较时结果为 false,这不能满足我们的要求,所以就需要对从基类Object中继承的该方法进行重写,以使其符合我们的要求。
3.应该如何重写equals方法?
重写equals方法时,除了最基本的要判断两个对象的类型是否相同,以及属性值是否相同之外,有很重要的一点就是需要重写其hashcode方法,因为java中规则约定:如果两个对象equals后的结果为true时,他们的hashcode值一定是相同的;如果equals的结果为false时,则应尽量使他们的hashcode值不同。
这么约定是为了避免在使用 HashMap,HashList等集合时出现冲突,因为在默认情况下每个对象的hashcode值是通过其内存地址经过计算得到的一个int型的值,所以每个对象的hashcode值是不同的。如果给HashMap中存入以下的键值对时:Map<Adress,String> map= new HashMap<Adress,String>(),即这里使用引用类型来做map集合的键,map集合中的键是不能重复的,在往map集合中存入数据时,当前的键值会跟已经存入的键值进行比较,而比较的方法正是使用hashcode.如果不重写hashcode,经我们重写equals后两个属性值相同的对象我们认为就是相同的,但他们的hashcode还是不同的,所以这里如果存入到map集合中时,map集合还认为他们依旧是两个不同的对象,依旧能够存入,这就不对了。所以一定要重写hashcode值, 让它符合java中的约定规则。这里重写的时候我们只需想办法让这个hashcode值能满足上面所说的约定即可。注意,这里的hashcode值的生成规则是我们根据自己的需求进行控制。
一般这里不需要我们自己来写,像eclipse工具可以帮我们自动生成重写的equals和hashcode方法,直接使用即可,这里贴上自动生成的代码,大家看看其实现原理
//重写的hashcode方法,使其满足约定
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((city == null) ? 0 : city.hashCode());
result = prime * result + ((province == null) ? 0 : province.hashCode());
return result;
}
//重写的equals方法,用来比较两个对象是否相同
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Address other = (Address) obj;
if (city == null) {
if (other.city != null)
return false;
} else if (!city.equals(other.city))
return false;
if (province == null) {
if (other.province != null)
return false;
} else if (!province.equals(other.province))
return false;
return true;
}
最后,附上两篇讲的比较透彻的文章以供大家参考:Java正确的自定义比较对象----如何重写equals方法和hashcode方法,Java哈希码以及equals和==的区别
关于重写对象equals方法的问题的更多相关文章
- java对象equals方法的重写
根类Object中的equals方法描述: public boolean equals(Object obj)The equals method for class Object implements ...
- 重写对象ToString方法
重写对象ToString方法,引入Newtonsoft.Json public override string ToString() { JsonSerializerSettings settings ...
- ExtJs--16--Ext.override()方法专门用来重写对象的方法
Ext.onReady(function(){ /** * Ext.override()方法专门用来重写对象的方法 */ //定义个类 Ext.define("U",{ //该类的 ...
- Java 如何重写对象的 equals 方法和 hashCode 方法
前言:Java 对象如果要比较是否相等,则需要重写 equals 方法,同时重写 hashCode 方法,而且 hashCode 方法里面使用质数 31.接下来看看各种为什么. 一.需求: 对比两个对 ...
- 为什么要重写equals()方法与hashCode()方法
在java中,所有的对象都是继承于Object类.Ojbect类中有两个方法equals.hashCode,这两个方法都是用来比较两个对象是否相等的. 在未重写equals方法我们是继承了object ...
- 重写equals方法的约定
1. 什么时候需要重写Object.equals方法 如果类具有自己特有的“逻辑相等”概念(不同于对象等同的概念),而且超类还没有覆盖equals以实现期望的行为,这时我们就需要覆盖equals方法. ...
- RemoveAll 要重写equals方法
public class User { private String name; private int age; //setter and getter public String getName( ...
- Effective Java 第三版——10. 重写equals方法时遵守通用约定
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- 【转】 如何重写hashCode()和equals()方法
转自:http://blog.csdn.net/neosmith/article/details/17068365 hashCode()和equals()方法可以说是Java完全面向对象的一大特色.它 ...
随机推荐
- (14)ASP.NET Core 中的日志记录
1.前言 ASP.NET Core支持适用于各种内置和第三方日志记录提供应用程序的日志记录API.本文介绍了如何将日志记录API与内置提供应用程序一起使用. 2.添加日志提供程序 日志记录提供应用程序 ...
- spark shuffle读操作
提出问题 1. shuffle过程的数据是如何传输过来的,是按文件来传输,还是只传输该reduce对应在文件中的那部分数据? 2. shuffle读过程是否有溢出操作?是如何处理的? 3. shuff ...
- springmvc原理详解(手写springmvc)
最近在复习框架 在快看小说网搜了写资料 和原理 今天总结一下 希望能加深点映像 不足之处请大家指出 我就不画流程图了 直接通过代码来了解springmvc的运行机制和原理 回想用springmvc用 ...
- HTTP与HTTPS之面试必备
本文主要讲解Http与https的区别,以及https是怎样加密来保证安全的. 首先讲这俩个协议的简单区别: HTTP:超文本传输协议. HTTPS:安全套接字层超文本传输协议HTTP+SSL HTT ...
- 使用sc 命令写脚本 添加和删除服务 简单应用
添加服务 @echo.服务启动...... @echo off @sc create 服务名 binPath= "%~dp0\服务路径" @sc config 服务名 start= ...
- html中video标签
video标签: <video src="视频的后缀名是.webM/.ogg/.mp4 "></video>属性: src:用于告诉video标签需要播放的 ...
- 逆向破解之160个CrackMe —— 018
CrackMe —— 018 160 CrackMe 是比较适合新手学习逆向破解的CrackMe的一个集合一共160个待逆向破解的程序 CrackMe:它们都是一些公开给别人尝试破解的小程序,制作 c ...
- C笔记_C语言环境、编译、预处理
1.环境 gcc -v //查看环境变量 gcc 同 g++ gcc main.c -o main.exe gcc main.c //默认生成a.exe 2.编译 预处理: gcc -E main ...
- Spark应用场景以及与hadoop的比较
一.大数据的四大特征: a.海量的数据规模(volume) b.快速的数据流转和动态的数据体系(velocity) c.多样的数据类型(variety) d.巨大的数据价值(value) 二.Spar ...
- stage_ros的world文件配置方法
官方文档参阅:http://rtv.github.io/Stage/modules.html stage_ros是一个基于stage的2D模拟器,用于ROS的仿真测试.虽然现在越来越多的人在使用gaz ...