@kiraSally
2018-03-12T18:34:08.000000Z
字数 2552
阅读 2114
JAVA
COLLECTIONS
源码
1.7版本
- 读者请先阅读笔者的 集合番@HashMap一文通(1.7版)
- 笔者个人博客 kiraSally的掘金个人博客 感谢支持
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
//维护一个HashMap作为底层数据结构
private transient HashMap<E,Object> map;
//Dummy value, HashSet存储时,将该值作为底层map的默认value
private static final Object PRESENT = new Object();
/**
* Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
* default initial capacity (16) and load factor (0.75).
*/
public HashSet() {
map = new HashMap<>();
}
/**
* 构造一个包含指定collection中的元素的新set。
* 实际底层使用默认的加载因子0.75和足以包含指定collection中所有元素的初始容量来创建一个HashMap。
* @param c 其中的元素将存放在此set中的collection。
*/
public HashSet(Collection<? extends E> c) {
map = new HashMap<E,Object>(Math.max((int) (c.size()/.75f) + 1, 16));
addAll(c);
}
/**
* 以指定的initialCapacity和loadFactor构造一个空的HashSet。
* 实际底层以相应的参数构造一个空的HashMap。
* @param initialCapacity 初始容量。
* @param loadFactor 加载因子。
*/
public HashSet(int initialCapacity, float loadFactor) {
map = new HashMap<>(initialCapacity, loadFactor);
}
/**
* 以指定的initialCapacity构造一个空的HashSet。
* 实际底层以相应的参数及加载因子loadFactor为0.75构造一个空的HashMap。
* @param initialCapacity 初始容量。
*/
public HashSet(int initialCapacity) {
map = new HashMap<>(initialCapacity);
}
/**
* 以指定的initialCapacity和loadFactor构造一个新的空链接哈希集合。此构造函数为包访问权限,不对外公开,实际只是是对LinkedHashSet的支持。实际底层会以指定的参数构造一个空LinkedHashMap实例来实现。
* @param initialCapacity 初始容量。
* @param loadFactor 加载因子。
* @param dummy 标记。
*/
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
/**
* 使用HashMap作为底层数据结构
* 1.利用HashMap的key不重复原则实现非重
* 2.由于HashMap的非有序导致HashSet的非有序
* 3.HashMap的value使用一个final的static变量作为默认值
* @Return 若put成功,返回true否则false (该方法在添加 key 不重复的键值对的时候,会返回 null)
*/
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
/**
* 返回此HashSet实例的浅表副本:并没有复制这些元素本身
* @Return 底层实际调用HashMap的clone()方法,获取HashMap的浅表副本
* 拓展:
* 1.浅复制就是仅复制类中的值类型成员
* 2.深复制就是复制类中的值类型成员和引用类型的成员
*/
public Object clone() {
try {
HashSet<E> newSet = (HashSet<E>) super.clone();
newSet.map = (HashMap<E, Object>) map.clone();
return newSet;
} catch (CloneNotSupportedException e) {
throw new InternalError();
}
}
/**
* 1.基于迭代器模式(Set接口定义Iterator<E> iterator()方法)
* 2.迭代map的keySet集合
*/
public Iterator<E> iterator() {
return map.keySet().iterator();
}
- 对于 HashSet 中保存的对象,请注意正确重写其
equals
和hashCode
方法,以保证放入的对象的唯一性- 有序可选用
LinkedHashSet
,TreeSet
- 线程安全可选用
CopyOnWriteArraySet
,ConcurrentSkipListSet
集合番@HashSet一文通(1.7版) 由 黄志鹏kira 创作,采用 知识共享 署名-非商业性使用 4.0 国际 许可协议 进行许可。
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名。