`
withoutme_hw
  • 浏览: 9433 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

Item 9: Always override hashCode when you override equals(Effective Java Chapter2笔记)

 
阅读更多
1.You must override hashCode in every class that overrides equals.
如果一个类实现了equals方法却没有实现hashCode方法,那么将这个对象A放入HashMap中,然后new一个与A相等的对象B,在HashMap中查找B,返回值将是null,因为没有实现hashCode方法,导致相等的两个对象返回的hash值不同(因为A==B为false)。
2.JavaSE6中关于hashCode方法的约定:
1)在应用的一次运行过程中,每一次调用hashCode方法的返回值必须是同一个整数,除非equals中使用到的值被改变。
2)如果两个对象调用equals返回true,那么他们的hashCode必须一样
3)如果两个对象调用equals方法返回false,不要求hashCode返回值必须不一样,但是如果返回的值不一样会提高hash tables的性能。
3.hashCode method recipe:
1. Store some constant nonzero value, say, 17, in an int variable called result.
2. For each significant field f in your object (each field taken into account by the equals method, that is), do the following:
a. Compute an int hash code c for the field:
i. If the field is a boolean, compute (f ? 1 : 0).
ii. If the field is a byte, char, short, or int, compute (int) f.
iii. If the field is a long, compute (int) (f ^ (f >>> 32)).
iv. If the field is a float, compute Float.floatToIntBits(f).
v. If the field is a double, compute Double.doubleToLongBits(f), and then hash the resulting long as in step 2.a.iii.
vi. 如果域是一个对象,则递归的调用hashCode,如果对象为null,返回0.
vii.如果是一个数组,把数组中的元素当做一个独立的域。如果数组中的每个元素都很重要,则使用Arrays.hashCode方法。
b. Combine the hash code c computed in step 2.a into result as follows: result = 31 * result + c;(选择31的原因:素数,且31 * i = (i << 5) - i,代码中无需这么写,因为JVM会自动优化)
4.return result
5.检查hashCode方法是否满足第2点中的约定。
4.为了提高效率,对于频繁调用的hashCode方法,可以将对象的hash值缓存起来
5.Do not be tempted to exclude significant parts of an object from the hashcode computation to improve performance.
有可能,大量的对象仅仅靠被你忽略的域来区分,这样HashMap中的数据会集中在一起。
Item 10: Always override toString
1.toString方法无需向equals和hashCode方法那样严格遵守约定,但是提供一个好的toString方法会使程序用起来很方便。
假设有一个PhoneNumber类,未实现toString方法,那么System.out.println("Failed to connect: " + phoneNumber);这样代码的结果很可能会是这样:{Jenny=PhoneNumber@163b91},无法提供充分的信息。

2.在实现toString方法时,一个重要的决定是要不要指定toString返回值的格式。The advantage of specifying the format is that it serves as a standard,unambiguous, human-readable representation of the object.可以很容易的在字符串和类之间相互转化。缺点是如果指定了格式标注,那么大量的客户端代码可能会依赖这个格式,所以这个格式将有可能永远不能再修改。Whether or not you decide to specify the format, you should clearly documentyour intentions.

3.Whether or not you specify the format, provide programmatic access to allof the information contained in the value returned by toString.如果没有提供,那么会强迫客户端转化字符串来获取对象的域,这将可能带来很多潜在的错误。
分享到:
评论

相关推荐

    Effective Java 3rd edition(Effective Java第三版英文原版)附第二版

    Item 11: Always override hashCode when you override equals Item 12: Always override toString Item 13: Override clone judiciously Item 14: Consider implementing Comparable 4 Classes and Interfaces Item...

    java 面对对象编程.pdf.zip

    为什么重写 equals() 时必须重写 hashCode() 方法? String String、StringBuffer、StringBuilder 的区别? String 为什么是不可变的? 字符串拼接用“+” 还是 StringBuilder? String#equals() 和 Object#equals() ...

    java集合知识-map、set等

    是通过对象的hashCode和equals方法来完成对象唯一性的。 如果对象的hashCode值不同,那么不用判断equals方法,就直接存储到哈希表中。 如果对象的hashCode值相同,那么要再次判断对象的equals方法是否为true。 ...

    JDBC_sorting_Comparing_

    Java sorting objects with equals and hashcode override

    疯狂JAVA讲义

    第1章 Java概述 1 1.1 Java语言的发展简史 2 1.2 Java的竞争对手及各自优势 4 1.2.1 C#简介和优势 4 1.2.2 Ruby简介和优势 4 1.2.3 Python的简介和优势 5 1.3 Java程序运行机制 5 1.3.1 高级语言的运行机制 6...

    javaclass源码-JavaForger:使用模板基于现有类生成Java源代码

    JavaForger包括通用Java代码的默认模板,例如equals,hashCode,innerBuilders和针对它们的单元测试。 可以为特定于项目的重复代码创建自定义模板。 JavaForger能够直接将源代码插入现有的类中。 例子 假设我们有一...

    JAVA基础课程讲义

    equals和hashcode方法 143  泛型 144 思考作业 145 上机作业 145 第八章 IO技术 146 为什么需要学习IO技术 146 基本概念 146 数据源 146 流的概念 146 第一个简单的IO流程序及深入(将文件中的数据读入) 146 Java...

    基于javatcpsocket通信的拆包和装包源码-java-interview:java基础知识点

    equals()&==&hashCode()&Object&hashMap String 和 StringBuffer的区别 Collection&Collections区别 hashSet如何保证不重复 什么是线程同步 进程 和 线程 Lock 和 Synchronized 的区别 常见的内存溢出 重载和重写的...

    AIC的Java课程1-6章

    第9章 常用类 4课时  理解Object类及其常用方法equals,hashCode和finalize等。  能够使用String,StringBuffer,StringBuilder类创建字符串对象和使用其方法,分辨不同类之间的区别。 ...

    安卓java读取网页源码-questions:自问自答

    安卓java读取网页源码 questions 自问自答 待初答 注:认真对待每一个答案。 Java String、StringBuilder 和 StringBuffer 有什么区别 == 和 equals 和 hashCode 有什么区别 说说你对 final 修饰符的理解 说说你对...

    ffmpeg-20170620-ae6f6d4-win64

    * @version 创建时间:2017年6月23日 上午9:13:12 * 类说明 */ public class FfmpegManager { private static ConcurrentMap, ConcurrentMap, Object&gt;&gt; handlerMap = new ConcurrentHashMap, ConcurrentMap, ...

    大华股份java笔试题-interviewer:面试官

    大华股份java笔试题 第一章 内容介绍 第二章 JavaSE 基础 一、 Java 面向对象 面向对象都有哪些特性以及你对这些特性的理解 访问权限修饰符 public、private、protected, 以及不写(默认)时的区别(2017-11-12) 如何...

    sesvc.exe 阿萨德

    * The load factor used when none specified in constructor. */ static final float DEFAULT_LOAD_FACTOR = 0.75f; static final int TREEIFY_THRESHOLD = 8; transient Node,V&gt;[] table; /** * Holds cached ...

    struts_2.3.12GA_API文档(chm版本)

    equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait 构造方法详细信息 ActionSupport public ActionSupport()方法详细信息 setActionErrors public void setActionErrors...

Global site tag (gtag.js) - Google Analytics