public class HashSet
extends AbstractSet
implements Set, Cloneable, java.io.Serializable
HashSet 继承了 AbstractSet类,可以使用父类的模板方法:
equals(Object o) ;
hashCode();
removeAll();
HashSet同时实现了 Set 接口和 Cloneable接口
HashSet类是Set接口最常用的实现类,采用hash算法存储数据,具有良好的存储和查找功能。
散列存储:不记录添加顺序;排列顺序时,顺序有可能发生变化;
线程不安全的,多个线程访问一个HashSet要使用同步代码;
HashSet集合元素值允许是null,但是最多只能有一个;
hash(翻译为哈希,或散列)算法的功能:
保证通过一个对象快速找到另一个对象;
其算法价值体现在速度,可以保证查询快速执行;
当从HashSet中访问元素时,HashSet先计算该元素的hashCode(也就是该对象的hashCode方法返回值),然后直接到该HashCode对应的位置取出该元素;
在这里对象的hashCode就好比是数组里的索引,但是不是索引;
HashSet 添加元素:
Set set = new HashSet();
set.add("Lucy");
先调用"Lucy".hashCode, 判断set集合里是否已经有了该hashCode;
1,不存在: 就直接把Lucy添加到set集合;
2,存在: 再比较 "Lucy"与"Lucy"一样的hashCode值的对象,使用对象的equals比较;
false: 就添加进set
true: 表明是同一个对象,add(Object e)就返回false,添加失败;
package collection;
import java.util.HashSet;
import java.util.Set;
class Employee{
private Long id;
private String Sn; //工号
private String name; //姓名
public int hashCode()
{
int idCode = (int)(id^(id >>> 32));
int snCode = sn.hashCode();
return idCode * 7 + snCode * 13;
}
public boolean equals(Object obj)
{
if(obj instanceof Employee)
{
Employee e = (Employee)obj;
return sn.equals(e.sn)
}
return false;
}
}public class SetDemo2()
{
public static void main(String[] args)
{
Set set = new HashSet();
set.add(new Employee());
set.add(new Employee());
}
}
hashCode计算方法:
字段类型(f) 计算方式
boolean hashCode=(f?0:1);
byte,short,char,int hashCode=(int)f;
long hashCode=(int)(f^(f>>>32));
float hashCode=Float.floatToIntBits(f);
double long l = Double.doubleToLongBits(f);
hashCode=(int)(l^(l>>>32))
引用类型 hashCode=f.hashCode();
实际开发中,可以使用EclipseIDE自动生成hashCode和equals方法。
Eclipse中右键, Source --> "Generate HashCode and equals Method"