紧接着来看一下Set篇的内容,Set篇的内容比较简单,需求就是当需要一个集合的元素不能重复时,使用Set集合,主要也就是HashSet这个集合。
HashSet
本来我以为HashSet的设计者会类似于HashMap的底层实现(因为HashMap的key不能重复)使用数组加链表来保存,事实就是如此,更夸张的时是直接使用HashMap,它的类里面就保存着HashMap的实例,然后取出其key的集合来完成,至于key对应的value,who care?
直接看源码:
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
static final long serialVersionUID = -5024744406713321676L;
//使用一个HashMap
private transient HashMap<E,Object> map;
//默认value的对象
private static final Object PRESENT = new Object();
//创建HashSet实例时直接new出HashMap实例
public HashSet() {
map = new HashMap<>();
}
//迭代器也直接取出map的keySet集合迭代器
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);
}
//当add一个元素时,由于在HashMap中有判断key是否为空以及
//key是否重复等一些列判断,所以这里直接就put一个键值对到
//hashMap中
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();
}
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(e);
}
}
}
-
无需多说了,看注释即可,HashSet就是HashMap实现的。
LinkedHashSet
和之前HashMap的关系一样,LinkedHashSet和HashSet的区别就是有顺序,先add的元素在遍历时会先展示出来,当然其内部实现也非常简单,就直接有现成的LinkedHashMap:
//构造函数
public LinkedHashSet() {
super(16, .75f, true);
}
//hashSet中map使用LinkedHashMap即可。
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
TreeSet
和TreeMap一样,带排序功能,使用树实现,这里涉及树的知识,后续再更新。