JAVA HashSet equals hashcode
来源:互联网 发布:递推算法 编辑:程序博客网 时间:2024/05/17 23:57
HashSet
(1)特点:
存储顺序与元素添加的顺序无关;
非同步的,如果多个线程要操作HashSet,要通过代码来保持同步。
集合元素值可以是null
(2)HashSet添加元素的过程:
首先调用hashCode()方法来得到该对象的hashCode值,然后根据该hashCode值决定对象在HashSet中的存储位置。
如果该位置上没有元素,则直接存入;
如果该位置上已经保存了元素,调用equals方法,判断这两个元素是否相同。
如果返回true,认为相同,不保存;
如果不相同,保存。此时会在这个存储位置采用链式存储结构,将后来的元素保存在这个位置。
结果为:
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速度很快的原因。
(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速度很快的原因。
================================================================
原创文章,转载请注明链接
- JAVA HashSet equals hashcode
- Java基础: HashSet 与 hashCode、equals
- Java基础: HashSet 与 hashCode、equals
- L6: HashSet、hashCode()、equals()
- Java中HashSet要重写equals方法和hashCode方法
- hashset重写hashcode和Equals
- HashSet(overwrite hashcode、equals方法、源码)
- HashSet集合---HashCode方法与equals方法
- hashset中hashcode和equals方法
- HashSet如何重写了hashcode()和equals()
- HashSet 的使用 自定义hashCode和equals
- HashSet存储元素equals() hashCode()方法重写
- HashSet以及重写equals()和hashCode()
- HashSet集合hashcode和equals的影响
- java中HashSet的add的使用,以及equals和hashcode的重写
- java基础之问题:请说出hashCode方法、equals方法、HashSet、HashMap之间的关系
- java中HashSet的add的使用,以及equals和hashcode的重写
- JAVA学习-序号2 HashSet初入门,hashCode和equals方法
- 软件汉化:OllyDBG 入门之五-- 破解注意事项(转)
- progressDialog的使用
- HDU 3240 Counting Binary Trees 数论-卡特兰数
- C语言那些事儿(一)
- C++数据结构--冒泡排序
- JAVA HashSet equals hashcode
- mysql 在某字段里追加字符的SQL语句
- android的各种权限
- js操作select控件的几种方法发布
- swt/jface控件的隐藏与显示
- checkbox 的allchose和antichose
- hdu Max Sum Plus Plus(最大m段子段和)
- C++多线程入门
- 有关div的位置,隐藏显示和移动