Java源碼解析之超級接口Map
前言
我們在前面說到的無論是鏈表還是數(shù)組,都有自己的優(yōu)缺點,數(shù)組查詢速度很快而插入很慢,鏈表在插入時表現(xiàn)優(yōu)秀但查詢無力。哈希表則整合了數(shù)組與鏈表的優(yōu)點,能在插入和查找等方面都有不錯的速度。我們之后要分析的HashMap就是基于哈希表實現(xiàn)的,不過在JDK1.8中還引入了紅黑樹,其性能進一步提升了。
今天我們來說一說超級接口Map。
一、接口Map
Map是基于Key-Value的數(shù)據(jù)格式,并且key值不能重復,每個key對應的value值唯一。Map的key也可以為null,但不可重復。
在看Map接口的方法前,我們先來看看Map.Entry接口。
二、接口Map.Entry
keySet()方法返回值是Map中key值的集合;entrySet()的返回值也是返回一個Set集合,此集合的類型為Map.Entry。
Map.Entry是Map聲明的一個內(nèi)部接口,此接口為泛型,定義為Entry<K,V>。它表示Map中的一個實體(一個key-value對)。接口中有g(shù)etKey(),getValue方法。
// 獲取對應的key K getKey(); // 獲取對應的value V getValue(); // 替換原有的value V setValue(V value); // 希望我們實現(xiàn)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()); }
三、一些重要的方法
// 返回當前數(shù)據(jù)個數(shù) int size(); // 是否為空 boolean isEmpty(); // 判斷是否包含key,這里用到了key的equals方法,所以key必須實現(xiàn)它 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(); // 希望我們實現(xiàn)equals和hashCode boolean equals(Object o); int hashCode();
四、超級實現(xiàn)類AbstractMap
對應于AbstractCollection,AbstractMap的作用也是類似的,主要是提供一些方法的實現(xiàn),減少具體實現(xiàn)類的代碼量,可以方便繼承。下面我們看看它都實現(xiàn)了哪些方法:
在看方法之前,先來看看定義的兩個變量吧:
transient Set<K> keySet; transient Collection<V> values;
方法:
// 返回大小,這里大小基于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(); }
除此之外,還提供了許多默認的實現(xiàn)方法,我們看其中一個吧
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還實現(xiàn)了equals、hashCode、toString、clone等方法,這樣在具體實現(xiàn)時可以省去很多工作。
到此這篇關(guān)于Java源碼解析之超級接口Map的文章就介紹到這了,更多相關(guān)Java超級接口Map內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!