equals()和hashCode()之间的关系
在Java的基类java.lang.Object中有两个非常重要的方法:
public boolean equals(Object obj)
public int hashCode()
对这两个方法的理解非常重要,特别是当用户自己定义对象,并将其存入到Map中的时候;
然而,即便是高级开发人员,有时候也搞不清楚如何正确的使用它们;
在这篇文章,我首先会展示一种常见的错误示例,然后解释如何正确的使用这两个方法;
常犯的错误
如下代码是常见的错误使用示例:
package simplejava;
import java.util.HashMap;
class Apple {
private String color;
public Apple(String color) {
this.color = color;
}
public boolean equals(Object obj) {
if (!(obj instanceof Apple))
return false;
if (obj == this)
return true;
return this.color.equals(((Apple) obj).color);
}
}
public class Q9 {
public static void main(String[] args) {
Apple a1 = new Apple("green");
Apple a2 = new Apple("red");
// hashMap stores apple type and its quantity
HashMap<Apple, Integer> m = new HashMap<Apple, Integer>();
m.put(a1, 10);
m.put(a2, 20);
System.out.println(m.get(new Apple("green")));
}
}
在这个例子中,一个绿色苹果对象成功存入到hashMap中,但是当我们要取出来的时候,得到的却是null;然而通过调试程序,我们确实看到了hashmap中的绿苹果对象;
错误原因-hashcode()方法导致
之所以出现这个错误是因为没有重写hashCode()方法导致的。
hashCode()和equals()的关系是这样的:
如果两个对象相等(equal),它们的hashcode一定相同;
如果两个对象有相同的hashcode,它们不一定相等(equal);
之所以这样设计是为了在Map中更快的查找到对象(相对于线性搜索);
一般Map都设计成数组+链表的结构,使用hashcode去查找对象需要两个步骤,首先使用hashcode定位数组下标索引,然后遍历该数组元素对应的链表,找到equals的元素;
Object默认的hashcode实现对于不同的对象会返回不同的值,因此,在上面那个例子中,不同的对象(即使同一个类型)有着不同的hashcode;
值的散列就像在车库储存货物,不同的货物能被存放到不同的车库。比较有效查找货物办法是将不同的货物存到不同的车库中,而不是同一个车库;
所以将hash值尽可能的分散是一个比较好的策略;
关于这个例子,解决办法是添加hashcode方法,这里我将使用颜色的长度作为示范,如下代码:
public int hashCode(){
return this.color.length();
}
译文链接:http://www.programcreek.com/2011/07/java-equals-and-hashcode-contract/
equals()和hashCode()之间的关系的更多相关文章
- java里equals和hashCode之间什么关系
如果要比较实际内存中的内容,那就要用equals方法,但是!!! 如果是你自己定义的一个类,比较自定义类用equals和==是一样的,都是比较句柄地址,因为自定义的类是继承于object,而objec ...
- "=="、equals、hashCode之间的区别
1. "=="分为两种情况: (1) 基本数据类型,比较的是其对应的值是否相等: (2) 引用类型,比较的是他们在内存中存放的地址(或者说,是否指向同意对象). 2. equals ...
- “==”、“equals()”、“hashcode()”之间的秘密
前言 万丈高楼平地起,今天的聊点基础而又经常让人忽视的话题,比如“==”与“equals()”区别?为何当我们重写完"equals()"后也要有必要去重写"hashcod ...
- 关于equals()和hashcode()的一些约定
本文章主要讨论和回答一下几个问题: equals()的四大特性 equals()和hashcode()之间的关系,为什么我们经常说这两个方法要么都重写,要么都不重写? HashMap.HashSet等 ...
- 彻底明白equals和hashCode
equals和hashCode方法 equals 我们知道equals是用来比较两个对象是否相等的,比如我们常用的String.equals方法 @Test public void test() { ...
- Java中的equals()和hashCode() - 超详细篇
前言 大家好啊,我是汤圆,今天给大家带来的是<Java中的equals()和hashCode() - 详细篇>,希望对大家有帮助,谢谢 文章纯属原创,个人总结难免有差错,如果有,麻烦在评论 ...
- 说说hashCode() 和 equals() 之间的关系?
上一篇关于介绍Object类下的几种方法时面试题时,提到equals()和hashCode()方法可能引出关于“hashCode() 和 equals() 之间的关系?”的面试题,本篇来解析一下这道基 ...
- Java中equals()和hashCode()的关系以及重写equals()和hashCode()的重要性
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6580647.html 一:关系 如果两个对象相等(equal),它们的hashcode一定相同: 如果两个对 ...
- ==、equals()、hashcode()的关系和区别
==.equals().hashcode()概念 ==:它的作用是判断两个对象的地址是不是相等.即,判断两个对象是不试同一个对象. equals():它的作用也是判断两个对象是否相等.但它一般有两种使 ...
随机推荐
- C#系统缓存全解析(转载)
C#系统缓存全解析 对各种缓存的应用场景和方法做了很详尽的解读,这里推荐一下 转载地址:http://blog.csdn.net/wyxhd2008/article/details/8076105
- 【SQL】找出行数与自增标识值不相等的表(即有缺行)
环境:mssql ent 2k8 r2 原理:遍历所有含自增列的用户表,用sp_spaceused过程分别获取每张表的行数并写入临时表,然后使用IDENT_CURRENT函数获取表的最大标识值,比较二 ...
- java调用Oracle分页存储过程
Java程序 package com.test; import java.sql.CallableStatement; import java.sql.Connection; import java. ...
- JsonConvert 使用注意事项之 Serializable
1.使用NuGet安装Newtonsoft.Json. 2.创建需要序列化的类. public class Person { public string Name{get;set;} public i ...
- js Date 时间格式化的扩展
js Date 时间格式化的扩展: Date.prototype.format = function (fmt) { var o = { , //月 "d+": this.getD ...
- [教学] 将 Form 内的控件变成 Style 简易运用
1. 在 Form 上放一个 TImage ,再一个 TText 到 Image 里面,并将 Image1.StyleName 设定为 BtnStyle,如下: 2.接着放一个 TButton,将 S ...
- Get,Post请求中文乱码问题有效解决方法
本文主要介绍如何有效解决web请求中的乱码问题,其实解决方法有很多种,不同的请求类型解决方法也不相同. 本文只介绍最方便的一种: 1.先修改jsp中的编码方式 2.针对Post方式提交的请求如果出现乱 ...
- 为什么正常安装并成功运行了Genymotion虚拟但是运行的时候启动的却是自带的模拟器?
最近因为这个问题困惑了好久,最终找到了解决思路: 点击genymotion——setting——ADB——Use sustom Android tools,找到电脑中SDK文件位置就可了! 希望自己坚 ...
- pm2 配置
---恢复内容开始--- 1. ecosystem.json { "apps": [ { "name": "name", // 项目名 &q ...
- 利用FileStream实现多媒体文件复制
利用FileStream实现多媒体文件复制的主要思路在于利用两个FileStream对象,一个读取字节,另一个对象写入字节既可. 涉及知识点: 1.通常我们操作的File类,FileS ...