4. Set
Set 是不包含重复元素的集合。可以更加正式地表达为,在 set 里面的元素 e1,e2, 不允许 e1.equals(e2), 而且最多有一个 null 元素。
Set 的主要方法如下,可以看出 List 和 Set 在方法上的区别了, List 能够根据类似于 index ,来找到元素的方法,而 set 只管往集合里面放东西,并不管其插入的顺序, List 有比较严格的插入顺序。
//Set 是否为空
boolean isEmpty();
// 是否包含指定元素
boolean contains(Object o);
// 遍历 Set
Iterator<E> iterator();
// 转化成数组
Object[] toArray();
// 添加元素
boolean add(E e);
// 清空集合
void clear();
// 只保留包含指定集合的元素
boolean retainAll(Collection<?> c);
4.1 HashSet
1 . HashSet 的数据结构和工作原理
HashSet 的基本数据结构是 HashMap , HashMap 的基本数据结构是哈希表和链表,在构造函数上可以参见 HashMap 的工作原理,和 HashMap 一样,影响性能的因素包括: set 的初始化容量大小,容量因子,和 HashCode 的构造,其主要方法实现如下:
/**
* 添加元素,注意是将 elment 作为 key 存进 HashupMap ,
* 同时指定所有对应的 element 的 value 都为同一个对象,
* 这样可以防止元素重复,同时可以看出 Hashset 允许
* 空元素
*/
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
/**
* 移除元素
*/
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}
/**
* 清空 set
*/
public void clear() {
map.clear();
}
/**
*Clone Set
*/
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();
}
}
public boolean contains(Object o) {
return map.containsKey(o);
}
public boolean isEmpty() {
return map.isEmpty();
}
public int size() {
return map.size();
}
public Iterator<E> iterator() {
return map.keySet().iterator();
}