在上一篇博客,咱們介紹了 Map 集合的一種典型實現 HashMap ,在 JDK1.8 中,HashMap 是由 數組+鏈表+紅黑樹構成,相對於早期版本的 JDK HashMap 實現,新增了紅黑樹做爲底層數據結構,在數據量較大且哈希碰撞較多時,可以極大的增長檢索的效率。瞭解 HashMap 的具體實現後,咱們再來介紹由 HashMap 做爲底層數據結構實現的一種數據結構——HashSet。(若是不瞭解 HashMap 的實現原理,建議先看看 HashMap,否則直接看 HashSet 是很難看懂的)。java
HashSet 是一個由 HashMap 實現的集合。元素無序且不能重複。c#
public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable
和前面介紹的大多數集合同樣,HashSet 也實現了 Cloneable 接口和 Serializable 接口,分別用來支持克隆以及支持序列化。還實現了 Set 接口,該接口定義了 Set 集合類型的一套規範。數組
//HashSet集合中的內容是經過 HashMap 數據結構來存儲的 private transient HashMap<E,Object> map; //向HashSet中添加數據,數據在上面的 map 結構是做爲 key 存在的,而value統一都是 PRESENT private static final Object PRESENT = new Object();
第一個定義一個 HashMap,做爲實現 HashSet 的數據結構;第二個 PRESENT 對象,由於前面講過 HashMap 是做爲鍵值對 key-value 進行存儲的,而 HashSet 不是鍵值對,那麼選擇 HashMap 做爲實現,其原理就是存儲在 HashSet 中的數據 做爲 Map 的 key,而 Map 的value 統一爲 PRESENT(下面介紹具體實現時會了解)。微信
①、無參構造數據結構
public HashSet() { map = new HashMap<>(); }
直接 new 一個 HashMap 對象出來,採用無參的 HashMap 構造函數,具備默認初始容量(16)和加載因子(0.75)。函數
②、指定初始容量spa
public HashSet(int initialCapacity) { map = new HashMap<>(initialCapacity); }
③、指定初始容量和加載因子code
public HashSet(int initialCapacity, float loadFactor) { map = new HashMap<>(initialCapacity, loadFactor); }
④、構造包含指定集合中的元素對象
public HashSet(Collection<? extends E> c) { map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16)); addAll(c); }
集合容量很好理解,這裏我介紹一下什麼是加載因子。在 HashMap 中,可以存儲元素的數量就是:總的容量*加載因子 ,新增一個元素時,若是HashMap集合中的元素大於前面公式計算的結果了,那麼就必需要進行擴容操做,從時間和空間考慮,加載因子通常都選默認的0.75。blog
public boolean add(E e) { return map.put(e, PRESENT)==null; }
經過 map.put() 方法來添加元素,在上一篇博客介紹該方法時,說明了該方法若是新插入的key不存在,則返回null,若是新插入的key存在,則返回原key對應的value值(注意新插入的value會覆蓋原value值)。
也就是說 HashSet 的 add(E e) 方法,會將 e 做爲 key,PRESENT 做爲 value 插入到 map 集合中,若是 e 不存在,則插入成功返回 true;若是存在,則返回false。
public boolean remove(Object o) { return map.remove(o)==PRESENT; }
調用 HashMap 的remove(Object o) 方法,該方法會首先查找 map 集合中是否存在 o ,若是存在則刪除,並返回該值,若是不存在則返回 null。
也就是說 HashSet 的 remove(Object o) 方法,刪除成功返回 true,刪除的元素不存在會返回 false。
public boolean contains(Object o) { return map.containsKey(o); }
調用 HashMap 的 containsKey(Object o) 方法,找到了返回 true,找不到返回 false。
HashSet<Integer> set = new HashSet<>(); set.add(1); set.add(2); //加強for循環 for(Integer i : set){ System.out.println(i); } //普通for循環 Iterator<Integer> iterator = set.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); }
本系列教程持續更新,能夠微信搜索「 IT可樂 」第一時間閱讀。回覆《電子書》有我爲你們特別篩選的書籍資料