JAVA HashSet equals hashcode

来源:互联网 发布:递推算法 编辑:程序博客网 时间:2024/05/17 23:57
HashSet
(1)特点:
存储顺序与元素添加的顺序无关;
非同步的,如果多个线程要操作HashSet,要通过代码来保持同步。
集合元素值可以是null


(2)HashSet添加元素的过程:
首先调用hashCode()方法来得到该对象的hashCode值,然后根据该hashCode值决定对象在HashSet中的存储位置。
如果该位置上没有元素,则直接存入;
如果该位置上已经保存了元素,调用equals方法,判断这两个元素是否相同。
如果返回true,认为相同,不保存;
如果不相同,保存。此时会在这个存储位置采用链式存储结构,将后来的元素保存在这个位置。

可以看到存储首先判断的是hashCode值,即使两个元素相同(equals),只要他们的hashcode不同,也能被保存进来,显然这是不符合set的定义的。

实际我们比较对象一般使用equals,当equals返回的结果为相等时,认为两个对象相同。此时HashSet的hashCode也应该相等,Treeset使用的comparator的结果也应该为相等。即避免存入相同的元素。因此,将一个对象方法放到HashSet中时,如果重写了equals,也要重写hashcode方法,保证两者的一致性。



import java.util.*;class Demo {public static void main(String[] args) {HashSet h = new HashSet();h.add(new Person(1,13));h.add(new Person(2,23));System.out.println(h.size());for(Object temp : h){System.out.println(temp.toString());}}}class Person{private int id;private int age;public Person(int id, int age){this.id = id;this.age = age;}public boolean equals(Object obj){System.out.println("调用equals判断与本存储位置的已有对象是否相同");return false;}public int hashCode(){System.out.println("调用hashCode计算Hashcode值,得到存储位置");return 1;}}


结果为:
F:\163netdisk\JAVA学习\java se>java Demo
调用hashCode计算Hashcode值,得到存储位置
调用hashCode计算Hashcode值,得到存储位置
调用equals判断与本存储位置的已有对象是否相同
2
调用hashCode计算Hashcode值,得到存储位置
Person@1
调用hashCode计算Hashcode值,得到存储位置
Person@1
可以看到先调用调用hashCode计算Hashcode值,得到存储位置。第二次存入时,由于hashcode均返回1,即存储位置相同,第二个元素计算得到的存储位置与第一个相同,此时需要判断这两个是否相同。equals均返回false,将两个元素都存储进来。
使用toString()输出hashCode可以看到两个元素的hashCode相同。






(3)hashCode复写的基本规则“


用作equals判断的成员变量都要用来计算hashcode。
equals相等的两个元素hashcode应该也相等。


重写的一般方式如下:
(a)把对象中每个有意义的成员(equals中使用的)计算出一个int行的hashCode值。
不同类型的Field计算HashCode的方式如下
boolean f hashcode=f?0:1;
byte/short/char/int fhashcode=(int)f
long f hashcode=(int)(f^(f>>>32))
float f hashCode=Float.floatToIntBits(f);
double f long lg = Double.doubleToLongBits(f);
hashCode=(int)(lg^(lg>>>32));
普通引用类型 f hashCode=f.hashCode();
(b)将a中计算出来的个Field的值组合计算出一个hashcode值返回。为了避免本来不相等,相加后相等的情况,可以给各Field乘以任意一个质数后再相加。
例如:hashCode=13*f1.hashCode()+17*(int)f2


(4)采用HashCode的优点
相当于以类似于数组的方式给每个元素添加了索引,通过索引可以快速的找到存储位置,得到元素。而不用一个一个的比较元素。HashSet为每个元素通过HashCode方法设置相应的HashCode值,HashCode值对应存储位置。这就是HashSet速度很快的原因。


================================================================

原创文章,转载请注明链接


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 笔记本关闭核显黑屏怎么办 驱动补丁被卸了怎么办 网络驱动被删了怎么办 新装系统网卡没驱动怎么办 核显没有dp口怎么办 苹果7屏幕太小了怎么办 苹果装系统卡住了怎么办 苹果7手机白屏黑苹果怎么办 衣服破了个洞怎么办 黑苹果自带升级怎么办 双显卡都禁用了怎么办 win10优盘识别不出来怎么办 黑苹果无限重启怎么办 水泥地面起砂怎么办?这几招很有用 跟老公没法过了怎么办 胃和肠子有点烂怎么办? 车的屏幕黑了怎么办 ios12玩游戏闪退怎么办 没网steam要登录怎么办 电脑有gta还需要安装怎么办 孤岛惊魂5卡顿怎么办 酷匠密码忘记了怎么办 战地1有时候卡死怎么办 战地一fps太低怎么办 Dnf与系统不兼容怎么办 使命召唤7显示w怎么办 战地3王者太卡怎么办 合金装备5消音器没了怎么办 红警基地没了怎么办 玩战地1帧数太低怎么办 战地1点游戏不开怎么办 ios耳机孔坏了怎么办? 吃泻药都不排便怎么办 上司离职了我该怎么办 我上司要辞职我怎么办 一方坚决不同意离婚我该怎么办 模拟农场车翻了怎么办 手机退出键坏了怎么办 dnf邮件发错了怎么办 手机提示sd卡已损坏怎么办 解压包文件数据损坏该怎么办