Set
作为和List
同层级的集合,却没有与之比肩的热度.我在平时也少用,并觉得有些许陌生.或许是他"蹭饭"的缘故吧
1.Set
public interface Set<E> extends Collection<E> {
上面便是Set
接口的定义信息了,只是简单的继承了Collection
,再结合Doc
注释,得出以下信息:
Set
不包含重复元素,最多包含一个null
元素(但这只是协议,还得看具体实现).- 是通过
equals()
方法实现重复判断的.
前排提示: 建议先阅读Map小节内容,因为在一些Set
实现里面用了很多和Map
的相关的内容,这么做的原因也是为了减少代码量,只需要测试一次,便可满足多处使用,但这样会接口之间的关系会很混乱.
2. HashSet
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
1. 概述
上述一些类说明就不说了,前面也提过.HashSet
由哈希表构成的Set
实现,不保证元素的迭代顺序,允许null
元素.等下我们就能看到,HashSet
其实很简单,因为他内部使用的就是HashMap
.
2.方法
private transient HashMap<E,Object> map;
// 默认的value值
private static final Object PRESENT = new Object();
public HashSet() {
map = new HashMap<>();
}
HashSet
再初始化时也初始化了内部的HashMap
对象,同时HashSet
自身的方法不多.看几个主要的.
add()
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
短短一行代码便完成了新增的操作,利用HashMap
的key
本身不能重复的特性,实现了HashSet
.对应的key
值就是我们要存储的值,而value
就是上述新创建的Object
对象.
3.杂谈
HashSet
其他方法亦是如此,都是使用的HashMap
的方法,所以HashSet
到这里就结束了.
3. LinkedHashSet
public class LinkedHashSet<E>
extends HashSet<E>
implements Set<E>, Cloneable, java.io.Serializable {
1.杂谈
这个类也特别特别简单,就几个方法,还都是用的HashSet
的,但是他是一个迭代有序的Set
实现,至于迭代有序,其实就是使用的LinkedHashMap
.
public LinkedHashSet(int initialCapacity, float loadFactor) {
super(initialCapacity, loadFactor, true);
}
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
看了上图,应该都懂了吧,所以,LinkedHashSet
也结束了.
其实TreeSet
大家应该也能猜到了,他使用的是TreeMap
,这点从构造函数也能看出.