博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java重写hashCode
阅读量:6673 次
发布时间:2019-06-25

本文共 2951 字,大约阅读时间需要 9 分钟。

hot3.png

以下内容总结自《 Effective Java
》。
1.
何时需要重写
equals()
当一个类有自己特有的“逻辑相等”概念(不同于对象身份的概念)。
2.
设计
equals()
[1]
使用 instanceof
操作符检查“实参是否为正确的类型”。
[2]
对于类中的每一个“关键域”,检查实参中的域与当前对象中对应的域值。
[2.1]
对于非 float
double
类型的原语类型域,使用 ==
比较;
[2.2]
对于对象引用域,递归调用 equals
方法;
[2.3]
对于 float
域,使用
Float.floatToIntBits(
afloat
)
转换为 int
,再使用 ==
比较;
[2.4]
对于 double
域,使用
Double.doubleToLongBits(
adouble
)
转换为 int
,再使用 ==
比较;
[2.5]
对于数组域,调用 Arrays.equals
方法。
3.
当改写
equals()
的时候,总是要改写
hashCode()
根据一个类的 equals
方法(改写后),两个截然不同的实例有可能在逻辑上是相等的,但是,根据 Object.hashCode
方法,它们仅仅是两个对象。因此,违反了“相等的对象必须具有相等的散列码”。
4.
设计
hashCode()
[1]
把某个非零常数值,例如 17
,保存在 int
变量 result
中;
[2]
对于对象中每一个关键域 f
(指 equals
方法中考虑的每一个域):
[2.1]boolean
型,计算 (f ? 0 : 1);
[2.2]byte,char,short
型,计算 (int);
[2.3]long
型,计算 (int) (f ^ (f>>>32));
[2.4]float
型,计算
Float.floatToIntBits(
afloat
) ;
[2.5]double
型,计算
Double.doubleToLongBits(
adouble
)
得到一个 long
,再执行 [2.3];
[2.6]
对象引用,递归调用它的 hashCode
方法 ;
[2.7]
数组域,对其中每个元素调用它的 hashCode
方法。
[3]
将上面计算得到的散列码保存到 int
变量 c
,然后执行 result=37*result+c;
[4]
返回 result
5.
示例
下面的这个类遵循上面的设计原则,重写了类的 equals()
hashCode()
package
com.zj.unit;
import
java.util.Arrays;
 
public
class
Unit {
   
private
short
ashort
;
   
private
char
achar
;
   
private
byte
abyte
;
   
private
boolean
abool
;
   
private
long
along
;
   
private
float
afloat
;
   
private
double
adouble
;
   
private
Unit
aObject
;
   
private
int
[]
ints
;
   
private
Unit[]
units
;
 
   
public
boolean
equals(Object o) {
      
if
(!(o
instanceof
Unit))
          
return
false
;
       Unit unit = (Unit) o;
      
return
unit.
ashort
==
ashort
              && unit.
achar
==
achar
              && unit.
abyte
==
abyte
              && unit.
abool
==
abool
              && unit.
along
==
along
              && Float.floatToIntBits(unit.
afloat
) == Float
                    
.floatToIntBits(
afloat
)
              && Double.doubleToLongBits(unit.
adouble
) == Double
                     .doubleToLongBits(
adouble
)
             
&& unit.
aObject
.equals(
aObject
)
&& equalsInts(unit.
ints
)
              && equalsUnits(unit.
units
);
    }
 
   
private
boolean
equalsInts(
int
[] aints) {
      
return
Arrays.equals(
ints
, aints);
    }
 
   
private
boolean
equalsUnits(Unit[] aUnits) {
      
return
Arrays.equals(
units
, aUnits);
    }
 
   
public
int
hashCode() {
      
int
result = 17;
       result = 37 * result + (
int
)
ashort
;
       result = 37 * result + (
int
)
achar
;
       result = 37 * result + (
int
)
abyte
;
       result = 37 * result + (
abool
? 0 : 1);
       result = 37 * result + (
int
) (
along
^ (
along
>>> 32));
       result = 37 * result + Float.floatToIntBits(
afloat
);
      
long
tolong = Double.doubleToLongBits(
adouble
);
       result = 37 * result + (
int
) (tolong ^ (tolong >>> 32));
       result = 37 * result +
aObject
.hashCode();
       result = 37 * result + intsHashCode(
ints
);
       result = 37 * result + unitsHashCode(
units
);
      
return
result;
    }
 
   
private
int
intsHashCode(
int
[] aints) {
      
int
result = 17;
      
for
(
int
i = 0; i < aints.
length
; i++)
           result = 37 * result + aints[i];
      
return
result;
    }
 
   
private
int
unitsHashCode(Unit[] aUnits) {
      
int
result = 17;
      
for
(
int
i = 0; i < aUnits.
length
; i++)
           result = 37 * result + aUnits[i].hashCode();
      
return
result;
    }
}

转载于:https://my.oschina.net/u/2350108/blog/506830

你可能感兴趣的文章
304. Range Sum Query 2D - Immutable
查看>>
Redis实现广告缓存、并完善缓存击穿
查看>>
如何绘制最美的鱼骨图?
查看>>
什么是session?什么是cookie?session和cookie有什么区别?
查看>>
javascript引擎执行的过程的理解--语法分析和预编译阶段
查看>>
百度正式发布PaddlePaddle深度强化学习框架PARL
查看>>
迟到但重要的事
查看>>
从零学前端第十三讲:AngularJs进阶-指令
查看>>
CSS之FFC/GFC
查看>>
Node.js 指南(不要阻塞事件循环或工作池)
查看>>
为你的AliOS Things应用增加自定义cli命令
查看>>
PHP工具篇:PHPStorm IDE使用CodeSniffer代码规范化管理
查看>>
ADB 命令(一)
查看>>
使用 Gatsby.js 搭建静态博客 1 关键文件
查看>>
BASE64编码乱码问题的浅层分析与解释
查看>>
underscore中的小技巧
查看>>
RAM SSO功能重磅发布 —— 满足客户使用企业本地账号登录阿里云
查看>>
微信小程序使用二次贝塞尔曲线画波浪
查看>>
网络之旅总览
查看>>
[基础] AHK函数对象系列-绑定函数对象v2
查看>>