HashSet是继承自AbstractSet,并且实现了Set、Cloneable、Serializable接口。
HashSet中没有重复的变量,并且遍历是无序的。是可序列化的,但是因为其内部的HashMap集合使用了transient关键字,所以是不可序列化的,序列化的只是HashMap的key和其负载系数、容量和键值对数量
HashSet源码比较简单,其内部原理实现依赖于Map集合。
1.HashSet的属性
private transient HashMap<E,Object> map;
// 用于作为保存在Map中的key对应的value
// 所有的key共用一个value
private static final Object PRESENT = new Object();
2.HashSet的构造器
// 采用HashMap的默认容量,即16,扩容因子为0.75
public HashSet() {
map = new HashMap<>();
}
// 如果根据一个Collection创建HashMap,则根据该Collection的大小,除以0.75+1
// 与16做比较,如果小于16,则取16,大于则取计算后的值作为容量
public HashSet(Collection<? extends E> c) {
map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
addAll(c);
}
// 自定义初始容量和负载因子的HashMap
// 如果初始容量小于0或者负载系数小于0,则会抛出异常
public HashSet(int initialCapacity, float loadFactor) {
map = new HashMap<>(initialCapacity, loadFactor);
}
// 自定义初始容量的HashMap
// 初始容量小于0会抛出异常
public HashSet(int initialCapacity) {
map = new HashMap<>(initialCapacity);
}
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
3.HashSet.add
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
4.HashSet.remove
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}
网友评论