翻译人员: 铁锚
翻译时间: 2013年11月15日
原文链接: Java equals() and hashCode() Contract

图1

Java所有对象的超类 java.lang.Object 有两个非常重要的方法定义:

public boolean equals(Object obj)
public int hashCode()

实践证明这两个方法是非常重要的,特别是用Map存储用户自定义对象时.然而,有些高级开发者也不一定知道如何合适的使用它们。
本文先用示例演示如何使用它们,然后解释 equals()方法和hashCode是如何协同工作.
1. 错误使用方式
下面是一个常见的错误用法:

import java.util.HashMap;public 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 == ((Apple) obj).color;}public static void main(String[] args) {Apple a1 = new Apple("green");Apple a2 = new Apple("red");//hashMap stores apple type and its quantityHashMap<Apple, Integer> m = new HashMap<Apple, Integer>();m.put(a1, 10);m.put(a2, 20);System.out.println(m.get(new Apple("green")));}
}

在此示例中,hashMap 已经保存了一个绿色的Apple对象,但想(通过程序中的方式)从map获取此对象时,apple 对象并未被找到.
上述代码的输出结果是: null. 但通过断点调试,可以确定此对象已经存在于hashMap中,截图如下:

图2

2. 此问题由hashCode()引起
问题的原因是没有重写"hashCode()"方法.
equals()方法与hashCode()的通用协定是:
2.1 如果两个对象相等(equal),那么必须拥有相同的哈希码(hash code)
2.2 即使两个对象有相同的哈希值(hash code),他们不一定相等.

Map的核心思想就是可以比线性查找更快. 通过散列值(hash)作为键(key)来定位对象的过程分为两步:
在Map内部,存储着一个顶层数组,顶层数组的每个元素指向其他的数组,查找或存储的时候,先根据key对象的hashCode()值计算出数组的索引,然后到这个索引找到所指向的第二层线性数组,使用equals方法来比较是否有相应的值(以返回或者存储).
Object类中的hashCode()默认为每个对象返回不同的int值,因此在上面的例子中,两个相等(equal)的对象,返回了不同的hashCode值.
解决方法是为此类添加hashCode方法,比如,使用color字符串的长度作为示范:

public int hashCode(){// 此种实现,要求 color值定以后就不得修改// 否则同一个物理对象,前后有两个不同的hashCode,逻辑上就是错的。return this.color.length();
}

相关文章:

  1. Java中Set的contains()方法
  2. HashMap vs. TreeMap vs. Hashtable vs. LinkedHashMap
  3. Top 8 Diagrams for Understanding Java
  4. Yet Another “Java Passes By Reference or By Value”?

转载于:https://www.cnblogs.com/lanzhi/p/6467078.html

equals()与hashCode()方法协作约定相关推荐

  1. 搞懂 Java equals 和 hashCode 方法

    搞懂 Java equals 和 hashCode 方法 分析完 Java List 容器的源码后,本来想直接进入 Set 和 Map 容器的源码分析,但是对于这两种容器,内部存储元素的方式的都是以键 ...

  2. Java基础提升篇:equals()与hashCode()方法详解

    概述 java.lang.Object类中有两个非常重要的方法: public boolean equals(Object obj) public int hashCode() Object类是类继承 ...

  3. java baseentity_如何在JPA的BaseEntity中实现equals()和hashcode()方法?

    我有一个BaseEntity类,它是我的应用程序中所有JPA实体的超类. @MappedSuperclass public abstract class BaseEntity implements S ...

  4. List去重为什么要写equals(),hashCode()方法

    一,各个集合的特点: Collection(集合):容器,用于存放对象(引用类型.基本类型需要自动装箱) List(列表):元素有序,元素可以重复 (有索引). 通过元素的equals()方法判断是否 ...

  5. 【Java基础】之深入讨论equals()和hashcode()方法

    这篇文章将详解介绍 Java 的 equals() 与 hashCode() 方法 我们知道 Object 类是类继承结构的基础,所以是每一个类的父类,所有的对象,包括数组,都实现了在 Object ...

  6. Java拾遗:001 - 重写 equals 和 hashCode 方法

    2019独角兽企业重金招聘Python工程师标准>>> 重写equals方法 在Java中Object类是一个具体类,但它设计的主要目的是为了扩展,所以它的所有非final方法,都被 ...

  7. 深入理解Java的equals和hashCode方法

    1.谈谈equals方法 相信大家对这个这个方法一定不陌生.该方法是Object基类里的非final方法(被设计成可覆盖的),下面我们来看看Object中是如何实现该方法的.源代码如下: public ...

  8. 学习Java编程equals()和hashCode()方法

    equals()和hashCode()区别? equals():反映的是对象或变量具体的值,即两个对象里面包含的值--可能是对象的引用,也可能是值类型的值. hashCode():计算出对象实例的哈希 ...

  9. Java重写equals和hashCode方法

    在日常程序中,我们习惯使用equals方法来比较两个对象,继承自Object的equals方法默认的比较两个对象的内存地址(String类重写了equals方法,比较字符串的内容).假如我们创建了两个 ...

  10. 关于equals和hashcode方法

    首先声明一下,这篇文章仅仅讨论引用类型 所有引用类型都是继承自Object类,Object类有两个重要的方法:equals(),hashCode()经常被使用,虽然表面上你可能看不到你的代码里使用ha ...

最新文章

  1. ThroughRain第一次冲刺(每天更新)
  2. 3 镜像仓库Harbor安装
  3. js参数使用时常犯的一个低级错误
  4. php总结1 ——php简介、工作原理、运行环境、文件构成、语法结构、注释
  5. 【转】深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第六节 理解垃圾回收GC,提搞程序性能****
  6. 【Level 08】U08 Positive Attitude L6 Join our virtual community
  7. (转)最临近插值-双线性插值算法原理
  8. 软件设计师真题及解析
  9. 常用加密算法--对称加密算法
  10. 服务器上文件共享有哪些协议,访问局域网共享文件使用的是什么协议
  11. timestamp和datetime的区别
  12. 2018这类程序员工资最高!年薪50万只能算一般
  13. python中开方和平方
  14. 悼念《人月神话》作者 Fred Brooks
  15. CleanMyMac X 4.8版本更新!
  16. c++ 中关于引用(1)
  17. 天嵌E9卡片i.mx6q-Linux12.04搭建nfs环境以及从nfs启动开发板
  18. 【工具使用】怎么设置SSH隧道(Port Forwarding)
  19. 风控指标 —— KS
  20. ctf-web-速度要快

热门文章

  1. paip. 解决php 以及 python 连接access无效的参数量。参数不足,期待是 1”的错误
  2. Rust: Rangechar 'a'..'z' 能干什么?......待续
  3. Rust: map中的问题,两种写法有什么不同?
  4. 机器学习笔记(二):矩阵、环境搭建、NumPy | 凌云时刻
  5. “医检助手”诚聘互联网运营总监
  6. html 超链接嵌套,嵌套的超链接区域,HTML源中没有嵌套的链接元素
  7. 【优化求解】基于matlab遗传算法求解函数极值问题【含Matlab源码 1198期】
  8. 【TWVRP】基于matlab蚁群算法求解带时间窗的车辆路径规划问题【含Matlab源码 921期】
  9. centos 对某ip开放 防火墙端口_Centos防火墙设置与端口开放的方法
  10. 强化学习在游戏中的作用_游戏中的强化学习