简介
HashSet
继承AbstractSet
类,实现Set
、Cloneable
、Serializable
接口。其中AbstractSet
提供 Set
接口的骨干实现,从而最大限度地减少了实现此接口所需的工作。Set接口是一种不包括重复元素的Collection
,它维持它自己的内部排序,所以随机访问没有任何意义。
hashSet
实现了Set
,但底层实际却是一个HashMap
,实现方法也是对底层HashMap
的调用
特点
- HashSet 基于 HashMap 实现,使用了 HashMap 的 K 作为元素存储,V 为 new Object() ,
- 在 add() 方法中如果两个元素的 Hash 值相同,则通过 equals 方法比较是否相等。
- 由于底层为HashMap,所以是线程不安全的
public class HashSet<E>
{
......
private transient HashMap<E,Object> map;//HashSet里面有一个HashMap
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
public HashSet() {
map = new HashMap<>();
}
......
public boolean add(E e) {//简单的方法转换
return map.put(e, PRESENT)==null;
}
......
}
底层源码
构造方法
/**
* 使用HashMap的默认容量大小16和默认加载因子0.75初始化map,构造一个HashSet
*/
public HashSet() {
map = new HashMap<E,Object>();
}
/**
* 构造一个指定Collection参数的HashSet,这里不仅仅是Set,只要实现Collection接口的容器都可以
*/
public HashSet(Collection<? extends E> c) {
map = new HashMap<E,Object>(Math. max((int) (c.size()/.75f) + 1, 16));
// 使用Collection实现的Iterator迭代器,将集合c的元素一个个加入HashSet中
addAll(c);
}
/**
* 使用指定的初始容量大小和加载因子初始化map,构造一个HashSet
*/
public HashSet( int initialCapacity, float loadFactor) {
map = new HashMap<E,Object>(initialCapacity, loadFactor);
}
/**
* 使用指定的初始容量大小和默认的加载因子0.75初始化map,构造一个HashSet
*/
public HashSet( int initialCapacity) {
map = new HashMap<E,Object>(initialCapacity);
}
/**
* 不对外公开的一个构造方法(默认default修饰),底层构造的是LinkedHashMap,dummy只是一个标示参数,无具体意义
*/
HashSet( int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<E,Object>(initialCapacity, loadFactor);
}
其他方法
hashSet
的其他方法都是对底层HashMap
的简单调用
public Iterator<E> iterator() {
return map.keySet().iterator();
}
public int size() {
return map.size();
}
public boolean isEmpty() {
return map.isEmpty();
}
public boolean contains(Object o) {
return map.containsKey(o);
}
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}
public void clear() {
map.clear();
}