數組與鏈表在處理數據時各有優缺點,數組查詢速度很快而插入很慢,鏈表在插入時表現優秀但查詢無力。哈希表則整合了數組與鏈表的優勢,能在插入和查找等方面都有不錯的速度。咱們以後要分析的HashMap
就是基於哈希表實現的,不過在JDK1.8中還引入了紅黑樹,其性能進一步提高了。本文主要分析JDK中關於Map
的定義。java
Map的定義爲:數組
An object that maps keys to values. A map cannot contain duplicate keys; each key can map to at most one value.性能
也就是基於key-value
的數據格式,而且key值不能夠重複,每一個key對應的value惟一。Map的key也能夠爲null,也不可重。學習
在分析其定義的方法前,咱們要先了解一下Map.Entry
這個接口。this
存儲在Map中的數據須要實現此接口,主要提供對key和value的操做,也是咱們使用最多的操做。咱們先分析它:code
// 獲取對應的key K getKey(); // 獲取對應的value V getValue(); // 替換原有的value V setValue(V value); // 但願咱們實現equals和hashCode boolean equals(Object o); int hashCode(); // 從1.8起,還提供了比較的方法,相似的方法共四個 public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> comparingByKey() { return (Comparator<Map.Entry<K, V>> & Serializable) (c1, c2) -> c1.getKey().compareTo(c2.getKey()); }
// 返回當前數據個數 int size(); // 是否爲空 boolean isEmpty(); // 判斷是否包含key,這裏用到了key的equals方法,因此key必須實現它 boolean containsKey(Object key); // 判斷是否有key保存的值是value,這也基於equals方法 boolean containsValue(Object value); // 經過key獲取對應的value值 V get(Object key); // 存入key-value V put(K key, V value); // 移除一個key-value對 V remove(Object key); // 從其餘Map添加 void putAll(Map<? extends K, ? extends V> m); // 清空 void clear(); // 返回全部的key至Set集合中,由於key是不可重的,Set也是不可重的 Set<K> keySet(); // 返回全部的values Collection<V> values(); // 返回key-value對到Set中 Set<Map.Entry<K, V>> entrySet(); // 但願咱們實現equals和hashCode boolean equals(Object o); int hashCode();
此外,還有一些Java8相關的default方法,就不一一展現了。blog
default V getOrDefault(Object key, V defaultValue) { V v; return (((v = get(key)) != null) || containsKey(key)) ? v : defaultValue; }
對應於AbstractCollection
,AbstractMap
的做用也是相似的,主要是提供一些方法的實現,能夠方便繼承。下面咱們看看它都實現了哪些方法:繼承
// 返回大小,這裏大小基於entrySet的大小 public int size() { return entrySet().size(); } public boolean isEmpty() { return size() == 0; } //基於entrySet操做 public boolean containsKey(Object key) { Iterator<Map.Entry<K,V>> i = entrySet().iterator(); if (key==null) { while (i.hasNext()) { Entry<K,V> e = i.next(); if (e.getKey()==null) return true; } } else { while (i.hasNext()) { Entry<K,V> e = i.next(); if (key.equals(e.getKey())) return true; } } return false; } public boolean containsValue(Object value) { //... } public V get(Object key) { //... } public V remove(Object key) { //... } public void clear() { entrySet().clear(); }
除此之外,還定義了兩個變量:接口
transient Set<K> keySet; transient Collection<V> values;
還提供了默認的實現方法,咱們只看其中一個吧:圖片
public Set<K> keySet() { Set<K> ks = keySet; if (ks == null) { ks = new AbstractSet<K>() { public Iterator<K> iterator() { return new Iterator<K>() { private Iterator<Entry<K,V>> i = entrySet().iterator(); public boolean hasNext() { return i.hasNext(); } public K next() { return i.next().getKey(); } public void remove() { i.remove(); } }; } public int size() { return AbstractMap.this.size(); } public boolean isEmpty() { return AbstractMap.this.isEmpty(); } public void clear() { AbstractMap.this.clear(); } public boolean contains(Object k) { return AbstractMap.this.containsKey(k); } }; keySet = ks; } return ks; }
除了以上相關方法之外,AbstractMap
還實現了equals
、hashCode
、toString
、clone
等方法,這樣在具體實現時能夠省去不少工做。
【感謝您能看完,若是可以幫到您,麻煩點個贊~】
更多經驗技術歡迎前來共同窗習交流: 一點課堂-爲夢想而奮鬥的在線學習平臺 http://www.yidiankt.com/
![關注公衆號,回覆「1」免費領取-【java核心知識點】]
QQ討論羣:616683098
QQ:3184402434
想要深刻學習的同窗們能夠加我QQ一塊兒學習討論~還有全套資源分享,經驗探討,等你哦!