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.如果没有提供,那么会强迫客户端转化字符串来获取对象的域,这将可能带来很多潜在的错误。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值