正确重写hashCode的办法
来源:互联网 发布:c语言点滴 pdf 百度云 编辑:程序博客网 时间:2024/05/22 15:22
——————————————————————————————————————————
正确重写hashCode的办法
[1]. hashCode重写成相同的值的缺点
将所有对象的hashCode都返回一样的值是不科学的。比如a1和a3这两个根本不同的对象,就没有必要去比较equals,增加无谓的计算量。所以应该对象本身的内容 (属性)来重写hashCode。
一旦两个对象内部不一样,就直接判定出hashCode不一样,不用再调用equals进行比较。
[2]. 正确书写hashCode的办法:
【原则】按照equals( )中比较两个对象是否一致的条件用到的属性来重写hashCode()。
{1}. 常用的办法就是利用涉及到的的属性进行线性组合。
{2}. 线性组合过程中涉及到的组合系数自定义即可。
注意,拼接之后的数值不能超过整形的表达范围。
{3}. 公式:属性1的int形式+ C1*属性2的int形式+ C2* 属性3的int形式+ …
【技巧】当属性是引用类型的时候,如果已经重写过hashCode(),那么这个引用属性的int形式就是直接调用属性已有的hashCode值。
最典型的就是这个属性是字符串类型的,String类型已经重写了hashCode()方法,所以直接拿来使用即可。
——————————————————————————————————————————
(1). 主要代码
- class
Person{ private String name; private int age; public static void sop(Object o){ System.out.println(o); } public Person(String intname, age){ this.name =name; this.age =age; } public void setName(String name){ this.name =name; } public String getName(){ return this.name; } public void setAge( intage){ this.age =age; } public int getAge(){ return this.age; } public String toString(){ return this.name+"::"+this.age; } //equals已经重写 - public
boolean equals(Object obj){ - if(!(obj
instanceof Person)){ return false; } Person p =(Person)obj; //用来查看equals方法是否被调用 sop(this.name + ".......equals......."+p.name); //认为名字相同并且年龄一样大的两个对象是一个 - return
this.name.equals(p.name) && this.age== p.age; - }
- }
(2). 将hashCode()重写成相同的值-----解决HashSet中重复添加
[1]. 问题:内容相同但是地址不同的自定义对象如何避免重复的内容添加到HashSet中?
【解决办法】必须重写hashCode和equals这两个方法
{1}. 此时根据底层哈希表的存储方式:哈希表会将具有相同哈希值的元素依次顺延。
{2}. hashCode值相同,HashSet在存储对象的时候,equals方法就会起作用
{3}. 示例代码:为Person类重写如下的hashCode代码
- public
int hashCode(){ System.out.println(this.name + "...hashCode");return 60; - }
这样,每一个Person对象都具有相同的哈希值。
打印结果:
【HashSet添加过程分析】
【1】a1率先存入HashSet中
添加的时候,调用一次a1的hashCode方法,打印一次a1...hashCode。由于开始HashSet中没有内容,所以没有调用a1的equals方法。
内存图如下:
【2】当a2要存入HashSet的时候,HashSet首先调用a2的hashCode方法,此时打印出a2...hashCode。发现a2的hashCode也是0x3c和a1的地址值都是一样的,此时要和a1进行内容比较,打印出a2.......equals.......a1。但是发现name和age都不一样,所以equals返回false。此时HashSet就将这个a2存到集合中来。
内存图如下:
【3】当a3要存入HashSet的时候,HashSet首先调用a3的hashCode方法,查看有没有地址相同的元素,此时打印出a3...hashCode。此时集合中已经存在两个元素a1和a2,发现a3的hashCode也是0x3c和a1、a2的地址值都是一样的,此时要一一和这些对象的内容进行比较。
比较发现a3和a1仍然是地址相同但是内容不同的元素。
a3就被认为是集合中以前并不存在的元素,所以仍然被添加进来。
内存图如下:
【4】当运行到第二个a2要添加进来的时候,先调用hashCode,所以马上打印a2...hashCode。
但是发现,和a2 hashCode相同的元素有a1、a2和a3。这个a2要和集合中的a1、a2和a3都做内容上是否相同的比较。
位置相同,但是内容不同。
但是发现两者内容、地址均相同,是重复的元素,不能加到集合中来,所以没有必要再把这个a2和集合中的a1进行比较。所以没有打印a2.......equals.......a1
(3). 正确重写hashCode的办法
[1]. hashCode重写成相同的值的缺点
将所有对象的hashCode都返回一样的值是不科学的。比如a1和a3这两个根本不同的对象,就没有必要去比较equals,增加无谓的计算量。所以应该对象本身的内容
一旦两个对象内部不一样,就直接判定出hashCode不一样,不用再调用equals进行比较。
e.g. 分析案例
这个例子中,重写的equals方法中是通过name和age来判定两个对象是否一致的。所以,就通过Person的这两个属性name和age的线性组合来获取这个Person的hashCode值。注意到name是String类型的,所以,可以调用name的hashCode()来直接获取name对应的int值。
这里重写的hashCode方法是:
public
}
打印结果:
- 正确重写hashCode的办法
- 正确重写hashCode的办法
- 如何正确的重写equals() 和 hashCode()方法
- 如何正确的重写equals() 和 hashCode()方法
- 正确重写equals()和hashCode()方法
- hashcode()的重写
- hashcode的重写方法
- 重写自己的hashCode()方法
- 重写自己的hashCode()方法
- 重写自己的hashCode()方法
- equals,hashCode,compareTo的重写
- java重写hashcode的方法
- 重写hashCode()方法的心得
- Hashcode和equals的重写
- equals和hashcode的重写
- 重写equalse()重写hashCode()
- Rubymine的正确打开办法 :)
- equals和hashcode的重写规则
- 准备蓝桥杯--dyx--01字串
- 《RFID技术与应用》第一部分基础理论学习
- 对分查找
- 一个html分页器的demo
- 图片缓存之内存缓存技术LruCache,软引用
- 正确重写hashCode的办法
- 手机HTML5 audio 无法自动播放下一首
- 准备蓝桥杯--dyx--判断闰年
- MarkDown中锚点的使用
- JAVA输出文件中的文件名
- UML类图几种关系的总结
- 用c语言实现闰年的查找或判断
- SQL2008无法连接到.\SQLEXPRESS,用户'sa'登录失败(错误18456)图文解决方法
- (四)yii修改表结构导致model创建表单出现字段为定义