JDK源碼分析Set類,因爲Set類是經常要用到的,那我們知道JDK源碼中Set類在其中不可以有相同的元素,那麼判斷這個元素是否相同是如何實現的呢,我們看下下面這張圖:
對JDK源碼分析之Set類在這張類圖上,首先我們看見一個經典模式的應用,那就是適配器模式,我們把map接口的對象,包裝成爲了Set的接口;在代碼中,我們來分析一下;
首先,我們看一下HashSet
- private transient HashMap map;
- // Dummy value to associate with an Object in the backing Map
- private static final Object PRESENT = new Object();
可見,他適配了HashMap,那麼他的功能是如何委託給HashMap結構的呢?
- public boolean add(E e) {
- return map.put(e, PRESENT)==null;
- }
在HashMap中,我們大多數時候是用value,但是在set的時候,卻很好的利用了已有類HashMap,他利用了HashMap的key的唯一性來保證存儲在Set中的元素的唯一性;
private static final Object PRESENT = new Object();
是這個HashMap所有key的value,他只是一個形式,而我們真正的數據是存在在key中的資源;
我們最後拿到的迭代器也是:
- public Iterator iterator() {
- return map.keySet().iterator();
- }
Map的keySet的迭代器;
同理,我們看看LinkedhashMap;
- public LinkedHashSet(int initialCapacity, float loadFactor) {
- super(initialCapacity, loadFactor, true);
- }
- /**
- * Constructs a new, empty linked hash set with the specified initial
- * capacity and the default load factor (0.75).
- *
- * @param initialCapacity the initial capacity of the LinkedHashSet
- * @throws IllegalArgumentException if the initial capacity is less
- * than zero
- */
- public LinkedHashSet(int initialCapacity) {
- super(initialCapacity, .75f, true);
- }
- /**
- * Constructs a new, empty linked hash set with the default initial
- * capacity (16) and load factor (0.75).
- */
- public LinkedHashSet() {
- super(16, .75f, true);
- }
調用了父類的構造函數;構造函數如下:
- HashSet(int initialCapacity, float loadFactor, boolean dummy) {
- map = new LinkedHashMap(initialCapacity, loadFactor);
- }
生出了LinkedHashMap;
同理,我們一樣可見到TreeMap的實現:
- private transient NavigableMap m;
- // Dummy value to associate with an Object in the backing Map
- private static final Object PRESENT = new Object();
更多的,我們也可以理解他是一種橋接模式的一種變形,不過我想從意義上,我更願意相信其是適配器的應用;
對JDK源碼分析之Set類到這裏,希望對你有幫助。