[关闭]
@kiraSally
2017-07-21 11:38
字数 2244
阅读 7
HashSet一文通
JAVA
COLLECTIONS
源码
1.什么是HashSet
- 底层采用HashMap保存元素
- 非重,无序,非同步
- 本版本基于JDK1.7
2.HashSet的数据结构
- 类定义
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);
}
3.HashSet的存储
- add方法解析
/**
* 使用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;
}
- clone方法解析
/**
* 返回此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 中保存的对象,请注意正确重写其
-
内容目录
-
- COLLECTIONS 3
- HashTable一文通
- HashSet一文通
- HashMap一文通
- JAVA 3
- HashTable一文通
- HashSet一文通
- HashMap一文通
- 以下【标签】将用于标记这篇文稿:
添加新批注
保存 取消 在作者公开此批注前,只有你和作者可见。
保存 取消
修改 保存 取消 删除
- 私有
- 公开
- 删除
查看更早的 5 条回复
回复批注
×
通知
取消 确认