JAVA中重写equals()方法为什么要重写hashcode()方法说明

重写hashCode()时最重要的原因就是:无论何时,对同一个对象调用hashCode()都应该生成同样的值。如果在将一个对象用put()方法添 加进HashMap时产生一个hashCode()值,而用get()取出时却产生了另外一个 hashCode()值,那么就无法重新取得该对象了。所以,如果你的hashCode()方法依赖于对象中易变的数据,那用户就要小心了,因为此数据发 生变化时,hashCode()就会产生一个不同的hash码,相当于产生了一个不同的“键”。

Object的hashCode()方法,返回的是当前对象的内存地址。下次如果我们需要取一个一样的“键”对应的键值对的时候,我们就无法得到一样的 hashCode值了。因为我们后来创建的“键”对象已经不是存入HashMap中的那个内存地址的对象了。

我们看一个简单的例子,就能更加清楚的理解上面的意思。假定我们写了一个类:Person (人),我们判断一个对象“人”是否指向同一个人,只要知道这个人的身份证号一直就可以了。

先来个没有重写Code类的hashcode()的例子吧,看看是什么效果:

Java代码  

  1. package com.fit;
  2. import java.util.HashMap;
  3. /**
  4. * 身份证类
  5. *
  6. * @author ZYD
  7. *
  8. */
  9. public class Code {
  10. /**
  11. * 身份证号码,一旦确定就不能更改
  12. */
  13. private final int id;
  14. public int getId() {
  15. return id;
  16. }
  17. /**
  18. * 通过构造方法确定身份证号码
  19. *
  20. * @param id
  21. */
  22. public Code(int id) {
  23. this.id = id;
  24. }
  25. /**
  26. * 重写equals()方法
  27. */
  28. public boolean equals(Object o) {
  29. // 如果地址一样,则两个对象相同
  30. if (this == o) {
  31. return true;
  32. }
  33. // 如果两个对象是同一类型,则比较其属性值是否都相同。如果都相同,则说明两个对象也相同;否则,说明这两个对象不相同。
  34. if (o instanceof Code) {
  35. Code co = (Code) o;
  36. boolean b = (co.id == this.id);
  37. return b;
  38. }
  39. return false;
  40. }
  41. /**
  42. * 重写toString()方法
  43. */
  44. public String toString() {
  45. return "【身份证】:" + id;
  46. }
  47. /**
  48. * 测试
  49. * @param args
  50. */
  51. public static void main(String[] args) {
  52. HashMap<Code, Person> map = new HashMap<Code, Person>();
  53. Person p1 = new Person(new Code(10001),"张三");
  54. Person p2 = new Person(new Code(10002),"李四");
  55. map.put(p1.getCode(), p1);
  56. map.put(p2.getCode(), p2);
  57. System.out.println("HashMap 中存放的人员信息:\n"+map);
  58. //张三改名为张山,身份证号不变。
  59. Person p3 = new Person(new Code(10001),"张山");
  60. map.put(p3.getCode(), p3);
  61. System.out.println("张三改名为张山后 HashMap 中存放的人员信息:\n"+map);
  62. //查找身份证为10001 的人员信息
  63. System.out.println("查找身份证为:10001 的人员信息:"+map.get(new Code(10001)));
  64. }
  65. }
  66. /**
  67. * 人类
  68. * @author Administrator
  69. *
  70. */
  71. class Person {
  72. /**
  73. * 每一个成人都有一个身份证
  74. */
  75. private Code code;
  76. /**
  77. * 姓名
  78. */
  79. private String name;
  80. public Code getCode() {
  81. return code;
  82. }
  83. public void setCode(Code code) {
  84. this.code = code;
  85. }
  86. public String getName() {
  87. return name;
  88. }
  89. public void setName(String name) {
  90. this.name = name;
  91. }
  92. public Person() {
  93. }
  94. public Person(Code code, String name) {
  95. this.code = code;
  96. this.name = name;
  97. }
  98. /**
  99. * 重写equals()方法 当两个人得身份证号相同以及姓名相同时,表示这两个人是同一个人。
  100. */
  101. public boolean equals(Object o) {
  102. if (o == this) {
  103. return true;
  104. }
  105. if (o instanceof Person) {
  106. Person p = (Person) o;
  107. boolean b = this.code.equals(p.code) && this.name.equals(p.name);
  108. return b;
  109. }
  110. return false;
  111. }
  112. /**
  113. * 重写toString()方法
  114. */
  115. public String toString() {
  116. return "【姓名】:" + name + "  ";
  117. }
  118. }

运行结果:

HashMap 中存放的人员信息:
{【身份证】:10002=【姓名】:李四  , 【身份证】:10001=【姓名】:张三  }
张三改名为张山后 HashMap 中存放的人员信息:
{【身份证】:10002=【姓名】:李四  , 【身份证】:10001=【姓名】:张三  , 【身份证】:10001=【姓名】:张山  }
查找身份证为:10001 的人员信息:null

从上面的结果可以看出:

我们所做的更新和查找操作都失败了。失败的原因就是我们的身份证类: Code 没有覆写 hashCode() 方法。这个时候,当查找一样的身份证号码的键值对的时候,使用的是默认的对象的内存地址来进行定位。这样,后面的所有的身份证号对象

new Code(10001) 产生的 hashCode () 值都是不一样的,所以导致操作失败。

重写Code类的hashcode(),代码上:

Java代码  

  1. package com.fit;
  2. import java.util.HashMap;
  3. /**
  4. * 身份证类
  5. *
  6. * @author ZYD
  7. *
  8. */
  9. public class Code {
  10. /**
  11. * 身份证号码,一旦确定就不能更改
  12. */
  13. private final int id;
  14. public int getId() {
  15. return id;
  16. }
  17. /**
  18. * 通过构造方法确定身份证号码
  19. *
  20. * @param id
  21. */
  22. public Code(int id) {
  23. this.id = id;
  24. }
  25. /**
  26. * 重写equals()方法
  27. */
  28. public boolean equals(Object o) {
  29. // 如果地址一样,则两个对象相同
  30. if (this == o) {
  31. return true;
  32. }
  33. // 如果两个对象是同一类型,则比较其属性值是否都相同。如果都相同,则说明两个对象也相同;否则,说明这两个对象不相同。
  34. if (o instanceof Code) {
  35. Code co = (Code) o;
  36. boolean b = (co.id == this.id);
  37. return b;
  38. }
  39. return false;
  40. }
  41. /**
  42. * 重写hashcode()方法,以身份证号码作为hash码。
  43. *
  44. * @return
  45. */
  46. public int hashCode() {
  47. return id;
  48. }
  49. /**
  50. * 重写toString()方法
  51. */
  52. public String toString() {
  53. return "【身份证】:" + id;
  54. }
  55. /**
  56. * 测试
  57. * @param args
  58. */
  59. public static void main(String[] args) {
  60. HashMap<Code, Person> map = new HashMap<Code, Person>();
  61. Person p1 = new Person(new Code(10001),"张三");
  62. Person p2 = new Person(new Code(10002),"李四");
  63. map.put(p1.getCode(), p1);
  64. map.put(p2.getCode(), p2);
  65. System.out.println("HashMap 中存放的人员信息:\n"+map);
  66. //张三改名为张山,身份证号不变。
  67. Person p3 = new Person(new Code(10001),"张山");
  68. map.put(p3.getCode(), p3);
  69. System.out.println("张三改名为张山后 HashMap 中存放的人员信息:\n"+map);
  70. //查找身份证为10001 的人员信息
  71. System.out.println("查找身份证为:10001 的人员信息:"+map.get(new Code(10001)));
  72. }
  73. }
  74. /**
  75. * 人类
  76. * @author Administrator
  77. *
  78. */
  79. class Person {
  80. /**
  81. * 每一个成人都有一个身份证
  82. */
  83. private Code code;
  84. /**
  85. * 姓名
  86. */
  87. private String name;
  88. public Code getCode() {
  89. return code;
  90. }
  91. public void setCode(Code code) {
  92. this.code = code;
  93. }
  94. public String getName() {
  95. return name;
  96. }
  97. public void setName(String name) {
  98. this.name = name;
  99. }
  100. public Person() {
  101. }
  102. public Person(Code code, String name) {
  103. this.code = code;
  104. this.name = name;
  105. }
  106. /**
  107. * 重写equals()方法 当两个人得身份证号相同以及姓名相同时,表示这两个人是同一个人。
  108. */
  109. public boolean equals(Object o) {
  110. if (o == this) {
  111. return true;
  112. }
  113. if (o instanceof Person) {
  114. Person p = (Person) o;
  115. boolean b = this.code.equals(p.code) && this.name.equals(p.name);
  116. return b;
  117. }
  118. return false;
  119. }
  120. /**
  121. * 重写toString()方法
  122. */
  123. public String toString() {
  124. return "【姓名】:" + name + "  ";
  125. }
  126. }

运行效果:

HashMap 中存放的人员信息:
{【身份证】:10001=【姓名】:张三  , 【身份证】:10002=【姓名】:李四  }
张三改名为张山后 HashMap 中存放的人员信息:
{【身份证】:10001=【姓名】:张山  , 【身份证】:10002=【姓名】:李四  }
查找身份证为:10001 的人员信息:【姓名】:张山

时间: 2024-09-30 05:45:05

JAVA中重写equals()方法为什么要重写hashcode()方法说明的相关文章

Java 中的 ==, equals 与 hashCode 的区别与联系

一.概述 1.概念 == : 该操作符生成的是一个boolean结果,它计算的是操作数的值之间的关系 equals : Object 的 实例方法,比较两个对象的content是否相同 hashCode : Object 的 native方法 , 获取对象的哈希值,用于确定该对象在哈希表中的索引位置,它实际上是一个int型整数 二.关系操作符 == 1.操作数的值 基本数据类型变量 在Java中有八种基本数据类型: 浮点型:float(4 byte), double(8 byte) 整型:byt

【转】Java中==、equals、hashcode的区别与重写equals以及hashcode方法实例

原文地址:http://www.cnblogs.com/luankun0214/p/4421770.html 感谢网友的分享,记录下来只为学习. 1.重写equals方法实例   部分代码参考http://blog.csdn.net/wangloveall/article/details/7899948 重写equals方法的目的是判断两个对象的内容(内容可以有很多,比如同时比较姓名和年龄,同时相同的才是用一个对象)是否相同 如果不重写equals,那么比较的将是对象的引用是否指向同一块内存地址

Java中==、equals、hashcode的区别与重写equals以及hashcode方法实例

1.重写equals方法实例   部分代码参考http://blog.csdn.net/wangloveall/article/details/7899948 重写equals方法的目的是判断两个对象的内容(内容可以有很多,比如同时比较姓名和年龄,同时相同的才是用一个对象)是否相同 如果不重写equals,那么比较的将是对象的引用是否指向同一块内存地址,重写之后目的是为了比较两个对象的value值是否相等.特别指出利用equals比较八大包装对象(如int,float等)和String类(因为该

Java中的equals和hashCode方法

本文转载自:Java中的equals和hashCode方法详解 Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要重写这两个方法. equals()和hashCode()方法是用来在同一类中做比较用的,尤其是在容器里如set存放同一类对象时用来判断放入的对象是否重复.这里我们首先要明白一个问题: equals()相等的两个对象,hashcode()一定相等,equals()不相等的两个对象,却并不能证明他们的h

java中‘==’和‘equals()’方法的有趣探索

这两天在看周志明的<深入理解java虚拟机>,受益颇多,根据书中的启示,对java中'=='和'equals()'方法的区别做了一些探索. 首先,为了更快地让进入状态,我们先来所几个判断题,例程如下,请判断各个System.out.println()输出的结果. <pre name="code" class="java"> public static void main(String[] args) { Integer a =1; Integ

Java中的equals和hashCode方法详解

Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要重写这两个方法,今天就来介绍一些这两个方法的作用. equals()和hashCode()方法是用来在同一类中做比较用的,尤其是在容器里如set存放同一类对象时用来判断放入的对象是否重复. 这里我们首先要明白一个问题: equals()相等的两个对象,hashcode()一定相等,equals()不相等的两个对象,却并不能证明他们的hashcode()不相等.换

【转】彻底弄懂Java中的equals()方法以及与&quot;==&quot;的区别

彻底弄懂Java中的equals()方法以及与"=="的区别 一.问题描述:今天在用Java实现需求的时候,发现equals()和“==”的功能傻傻分不清,导致结果产生巨大的偏差.所以,我决定花费时间把equals()和“==”的功能彻底弄懂,前事不忘后事之师嘛,分享给大家,希望对大家理解equals()和“==”的功能有所帮助. 二.分析探索解决问题的方法:1.Object 中的equals()方法: (1)通过查找API,说明如下: equalspublic boolean equ

看Java中==、equals、hashCode的来龙去脉

我有一个哥们去参加了面试,面试官这样问一个Java问题: 你说一下java对象的equals方法调用什么方法呢?我这个哥们想了想,回答说"应该是比较的引用".听了这个答案之后,那个面试官摇头晃脑的说:"不对,你回答的不对,equals方法调用的是hashCode方法".于是乎,我那个技术还不错的哥们就悲壮地栽在这道题目上了. 今天晚上,西安历史上少有的热,那就好好总结一下这个题目的来龙去脉好了,也方便给后面的朋友们提个醒,不要栽在这么简单的问题上.你说这个面试官回答

【转】浅谈Java中的equals和==

浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str2 = new String("hello"); 3 4 System.out.println(str1==str2); 5 System.out.println(str1.equals(str2)); 为什么第4行和第5行的输出结果不一样?==和equals方法之间的区别是什么?如果在初

【Java学习笔记之二十九】Java中的&quot;equals&quot;和&quot;==&quot;的用法及区别

Java中的"equals"和"=="的用法及区别 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str2 = new String("hello"); 3 System.out.println(str1==str2); 4 System.out.println(str1.equals(str2)); 为什么第4行和第5行的输出结果不一