在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()之间的关系的更多相关文章

  1. java里equals和hashCode之间什么关系

    如果要比较实际内存中的内容,那就要用equals方法,但是!!! 如果是你自己定义的一个类,比较自定义类用equals和==是一样的,都是比较句柄地址,因为自定义的类是继承于object,而objec ...

  2. "=="、equals、hashCode之间的区别

    1. "=="分为两种情况: (1) 基本数据类型,比较的是其对应的值是否相等: (2) 引用类型,比较的是他们在内存中存放的地址(或者说,是否指向同意对象). 2. equals ...

  3. “==”、“equals()”、“hashcode()”之间的秘密

    前言 万丈高楼平地起,今天的聊点基础而又经常让人忽视的话题,比如“==”与“equals()”区别?为何当我们重写完"equals()"后也要有必要去重写"hashcod ...

  4. 关于equals()和hashcode()的一些约定

    本文章主要讨论和回答一下几个问题: equals()的四大特性 equals()和hashcode()之间的关系,为什么我们经常说这两个方法要么都重写,要么都不重写? HashMap.HashSet等 ...

  5. 彻底明白equals和hashCode

    equals和hashCode方法 equals 我们知道equals是用来比较两个对象是否相等的,比如我们常用的String.equals方法 @Test public void test() { ...

  6. Java中的equals()和hashCode() - 超详细篇

    前言 大家好啊,我是汤圆,今天给大家带来的是<Java中的equals()和hashCode() - 详细篇>,希望对大家有帮助,谢谢 文章纯属原创,个人总结难免有差错,如果有,麻烦在评论 ...

  7. 说说hashCode() 和 equals() 之间的关系?

    上一篇关于介绍Object类下的几种方法时面试题时,提到equals()和hashCode()方法可能引出关于“hashCode() 和 equals() 之间的关系?”的面试题,本篇来解析一下这道基 ...

  8. Java中equals()和hashCode()的关系以及重写equals()和hashCode()的重要性

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6580647.html  一:关系 如果两个对象相等(equal),它们的hashcode一定相同: 如果两个对 ...

  9. ==、equals()、hashcode()的关系和区别

    ==.equals().hashcode()概念 ==:它的作用是判断两个对象的地址是不是相等.即,判断两个对象是不试同一个对象. equals():它的作用也是判断两个对象是否相等.但它一般有两种使 ...

随机推荐

  1. Jquery请求Ajax的json数据

      获得单个json对象 $.getJSON("test.js", { name: "John", time: "2pm" }, funct ...

  2. C# redis使用之ServiceStack

    需要注意的是:ServiceStack.Redis 中GetClient()方法,只能拿到Master redis中获取连接,而拿不到slave 的readonly连接.这样 slave起到了冗余备份 ...

  3. 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 ...

  4. Raising Error Conditions with MySQL SIGNAL / RESIGNAL Statements

    http://www.mysqltutorial.org/mysql-signal-resignal/ Summary: in this tutorial, you will learn how to ...

  5. 良好Web系统架构的几个因素

    好像以前整理过一些思路. 这里的架构不是指纵向的架构,而是横向的架构方面. 三个词:挂件化.模块化.钩子化.

  6. 泛函编程(33)-泛函IO:Free Functor - Coyoneda

    在前几期讨论中我们终于推导出了Free Monad.这是一个Monad工厂,它可以把任何F[A]变成Monad.可惜的是它对F[A]是有所要求的:F必须是个Functor.Free Monad由此被称 ...

  7. collection中的retainAll()方法

    public class ArraylistDemo { public static void main(String[] args) { Collection list1 = new ArrayLi ...

  8. 【Asphyre引擎】冒险岛换装Demo升级到最新版PXL

    demo代码  (不包含Sprite代码,要Sprite代码请下载之前那个doudou的demo)

  9. 一个java实习生两周八次的面试经历

    以前从来没有因为求职出去面试过,一直觉得面试很可怕,没想到最近两周我也成为了面霸,两周面试八次,我的找工作之路就这样开始了!大概两个星期之前,我看着自己在招聘网站上写好的简历连投出去的勇气都没有,战战 ...

  10. ahjesus 单词单数-复数相互转换C#

    看codesmith内置的模板在生成存储过程的时候有单复数的转换,用相同的函数名实现了一个 public static class StringUtil { /// <summary> / ...