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():它的作用也是判断两个对象是否相等.但它一般有两种使 ...
随机推荐
- Jquery请求Ajax的json数据
获得单个json对象 $.getJSON("test.js", { name: "John", time: "2pm" }, funct ...
- C# redis使用之ServiceStack
需要注意的是:ServiceStack.Redis 中GetClient()方法,只能拿到Master redis中获取连接,而拿不到slave 的readonly连接.这样 slave起到了冗余备份 ...
- error: Error retrieving parent for item: No resource found that matches the given name 'Theme.AppCompat.Light'.
error: Error retrieving parent for item: No resource found that matches the given name 'Theme.AppCom ...
- Raising Error Conditions with MySQL SIGNAL / RESIGNAL Statements
http://www.mysqltutorial.org/mysql-signal-resignal/ Summary: in this tutorial, you will learn how to ...
- 良好Web系统架构的几个因素
好像以前整理过一些思路. 这里的架构不是指纵向的架构,而是横向的架构方面. 三个词:挂件化.模块化.钩子化.
- 泛函编程(33)-泛函IO:Free Functor - Coyoneda
在前几期讨论中我们终于推导出了Free Monad.这是一个Monad工厂,它可以把任何F[A]变成Monad.可惜的是它对F[A]是有所要求的:F必须是个Functor.Free Monad由此被称 ...
- collection中的retainAll()方法
public class ArraylistDemo { public static void main(String[] args) { Collection list1 = new ArrayLi ...
- 【Asphyre引擎】冒险岛换装Demo升级到最新版PXL
demo代码 (不包含Sprite代码,要Sprite代码请下载之前那个doudou的demo)
- 一个java实习生两周八次的面试经历
以前从来没有因为求职出去面试过,一直觉得面试很可怕,没想到最近两周我也成为了面霸,两周面试八次,我的找工作之路就这样开始了!大概两个星期之前,我看着自己在招聘网站上写好的简历连投出去的勇气都没有,战战 ...
- ahjesus 单词单数-复数相互转换C#
看codesmith内置的模板在生成存储过程的时候有单复数的转换,用相同的函数名实现了一个 public static class StringUtil { /// <summary> / ...