日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

jdk1.8.0_45源码解读——Map接口和AbstractMap抽象类的实现

發布時間:2025/7/14 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jdk1.8.0_45源码解读——Map接口和AbstractMap抽象类的实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

jdk1.8.0_45源碼解讀——Map接口和AbstractMap抽象類的實現

一、 Map架構

如上圖:
(01) Map 是映射接口,Map中存儲的內容是鍵值對(key-value)。
(02) AbstractMap 是繼承于Map的抽象類,它實現了Map中的大部分API。其它Map的實現類可以通過繼承AbstractMap來減少重復編碼。
(03) SortedMap 是繼承于Map的接口。SortedMap中的內容是排序的鍵值對,排序的方法是通過比較器(Comparator)。
(04) NavigableMap 是繼承于SortedMap的接口。相比于SortedMap,NavigableMap有一系列的導航方法;如"獲取大于/等于某對象的鍵值對"、“獲取小于/等于某對象的鍵值對”等等。
(05) TreeMap 繼承于AbstractMap,且實現了NavigableMap接口;因此,TreeMap中的內容是“有序的鍵值對”!
(06) HashMap 繼承于AbstractMap,但沒實現NavigableMap接口;因此,HashMap的內容是“鍵值對,但不保證次序”!
(07) Hashtable 雖然不是繼承于AbstractMap,但它繼承于Dictionary(Dictionary也是鍵值對的接口),而且也實現Map接口;因此,Hashtable的內容也是“鍵值對,也不保證次序”。但和HashMap相比,Hashtable是線程安全的,而且它支持通過Enumeration去遍歷。
(08) WeakHashMap 繼承于AbstractMap。它和HashMap的鍵類型不同,WeakHashMap的鍵是“弱鍵”

?

二、 Map接口

1. Map.Entry<K, V>的結構

  映射項(鍵-值對)。Map.entrySet() 方法返回映射的 collection 視圖,其中的元素屬于此類。獲得映射項引用的唯一 方法是通過此 collection 視圖的迭代器來實現。這些 Map.Entry 對象僅在迭代期間有效;更確切地講,如果在迭代器返回項之后修改了底層映射,則某些映射項的行為是不確定的,除了通過 setValue 在映射項上執行操作之外。

K getKey();         //返回此項中對應的鍵值 V getValue();          //返回此項中對應的值 V setValue(V value);     //用指定的值替換與此項對應的值 boolean equals(Object o);   //比較指定對象與此項的相等性 int hashCode();         //返回此項的哈希碼

?

2. Map接口

將鍵映射到值的對象。一個映射不能包含重復的鍵;每個鍵最多只能映射到一個值。

Map 接口提供三種collection 視圖,允許以鍵集、值集或鍵-值映射關系集的形式查看某個映射的內容。映射順序 定義為迭代器在映射的 collection 視圖上返回其元素的順序。某些映射實現可明確保證其順序,如 TreeMap 類;另一些映射實現則不保證順序,如 HashMap 類。

注:將可變對象用作映射鍵時必須格外小心。當對象是映射中某個鍵時,如果以影響 equals 比較的方式更改了對象的值,則映射的行為將是不確定的。此項禁止的一種特殊情況是不允許某個映射將自身作為一個鍵包含。雖然允許某個映射將自身作為值包含,但請格外小心:在這樣的映射上 equals 和 hashCode 方法的定義將不再是明確的。

public interface Map<K,V> {int size();boolean isEmpty();boolean containsKey(Object key);boolean containsValue(Object value);V get(Object key);V put(K key, V value);V remove(Object key);void putAll(Map<? extends K, ? extends V> m);void clear(); Set<K> keySet();Collection<V> values();//返回此映射中包含的映射關系的 set 視圖Set<Map.Entry<K, V>> entrySet();boolean equals(Object o);int hashCode(); }

?

三、AbstractMap抽象類

1. AbstractMap.SimpleEntry<K, V>的結構

  SimpleEntry<K, V>是維護鍵和值的 Entry。可以使用 setValue() 方法更改值。此類簡化了構建自定義映射實現的過程。例如,可以使用 Map.entrySet().toArray 方法方便地返回 SimpleEntry實例數組。

public static class SimpleEntry<K,V>implements Entry<K,V>, java.io.Serializable{private static final long serialVersionUID = -8499721149061103585L;private final K key;private V value;//創建一個項,它表示從指定鍵到指定值的映射關系public SimpleEntry(K key, V value) {this.key = key;this.value = value;}//創建一個項,它表示的映射關系與指定的項相同public SimpleEntry(Entry<? extends K, ? extends V> entry) {this.key = entry.getKey();this.value = entry.getValue();}//返回對應于此項的鍵public K getKey() {return key;}//返回對應于此項的值public V getValue() {return value;}//用指定值替換對應于此項的值,并返回舊值public V setValue(V value) {V oldValue = this.value;this.value = value;return oldValue;}//相等性檢測,包括null值private static boolean eq(Object o1, Object o2) {return o1 == null ? o2 == null : o1.equals(o2);}//比較指定對象與此項的相等性public boolean equals(Object o) {if (!(o instanceof Map.Entry))return false;Map.Entry<?,?> e = (Map.Entry<?,?>)o;return eq(key, e.getKey()) && eq(value, e.getValue());}//返回此映射項的哈希值:key值的哈希碼與value值的哈希碼按位異或的結果public int hashCode() {return (key == null ? 0 : key.hashCode()) ^(value == null ? 0 : value.hashCode());}//返回此映射項的 String表示形式:key=valuepublic String toString() {return key + "=" + value;}} View Code

?

2.AbstractMap.SimpleImmutableEntry<K,V>的結構

  SimpleImmutableEntry<K,V>是維護不可變的鍵和值的 Entry,不支持setValue()方法。方便用于在返回線程安全的鍵-值映射關系的方法。

public static class SimpleImmutableEntry<K,V>implements Entry<K,V>, java.io.Serializable{private static final long serialVersionUID = 7138329143949025153L;private final K key;private final V value;//創建一個項,它表示從指定鍵到指定值的映射關系public SimpleImmutableEntry(K key, V value) {this.key = key;this.value = value;}//創建一個項,它表示的映射關系與指定項相同public SimpleImmutableEntry(Entry<? extends K, ? extends V> entry) {this.key = entry.getKey();this.value = entry.getValue();}//返回對應于此項的鍵public K getKey() {return key;}//返回對應于此項的值public V getValue() {return value;}//該方法僅拋出UnsupportedOperationException,表明該Entry不支持setValue方法public V setValue(V value) {throw new UnsupportedOperationException();}//比較指定對象與此項的相等性public boolean equals(Object o) {if (!(o instanceof Map.Entry))return false;Map.Entry<?,?> e = (Map.Entry<?,?>)o;return eq(key, e.getKey()) && eq(value, e.getValue());}//返回此映射項的哈希值:key值的哈希碼與value值的哈希碼按位異或的結果public int hashCode() {return (key == null ? 0 : key.hashCode()) ^(value == null ? 0 : value.hashCode());}//返回此映射項的 String表示形式:key=valuepublic String toString() {return key + "=" + value;}} View Code

?

3. AbstractMap抽象類

AbstractMap類提供 Map接口的骨干實現,以最大限度地減少實現此接口所需的工作。
要實現不可修改的映射,編程人員只需擴展此類并提供 entrySet() 方法的實現即可,該方法將返回映射的映射關系 set視圖。通常,返回的 set 將依次在 AbstractSet 上實現。此 set不支持 add() 或 remove() 方法,其迭代器也不支持 remove() 方法。

要實現可修改的映射,編程人員必須另外重寫此類的put() 方法(否則將拋出 UnsupportedOperationException),entrySet().iterator() 返回的迭代器也必須另外實現其 remove() 方法。

public abstract class AbstractMap<K,V> implements Map<K,V> {//構造函數protected AbstractMap() {}//返回此映射中的鍵-值映射關系數public int size() {return entrySet().size();}//如果此映射未包含鍵-值映射關系,則返回 true。public boolean isEmpty() {return size() == 0;}//如果鍵值對<key,value>集合中包含指定的value值,則返回turepublic boolean containsValue(Object value) {//entrySet()返回此映射中包含的映射關系的Set視圖Iterator<Entry<K,V>> i = entrySet().iterator(); //Map中允許value值為null,故分兩種情況考慮if (value==null) {while (i.hasNext()) {Entry<K,V> e = i.next();if (e.getValue()==null)return true;}} else {while (i.hasNext()) {Entry<K,V> e = i.next();if (value.equals(e.getValue()))return true;}}return false;}//如果鍵值對<key,value>集合中包含指定的key值,則返回turepublic boolean containsKey(Object key) {//entrySet()返回此映射中包含的映射關系的Set視圖Iterator<Map.Entry<K,V>> i = entrySet().iterator();//Map中只允許有唯一一個null的key值,故分兩種情況考慮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;}//返回指定鍵所映射的值;如果此映射不包含該鍵的映射關系,則返回 nullpublic V get(Object key) {Iterator<Entry<K,V>> i = entrySet().iterator();if (key==null) {while (i.hasNext()) {Entry<K,V> e = i.next();if (e.getKey()==null)return e.getValue();}} else {while (i.hasNext()) {Entry<K,V> e = i.next();if (key.equals(e.getKey()))return e.getValue();}}return null;}//將指定的值與此映射中的指定鍵關聯public V put(K key, V value) {throw new UnsupportedOperationException();}/*** 如果存在一個鍵的映射關系,則將其從此映射中移除。并返回以前與key關聯的值;如果沒有key的映射關系,則返回null** 注意,如果 entrySet()返回的集合所調用的迭代器不支持 remove方法,并且此映射包含指定鍵的映射關系,* 則此實現將拋出 UnsupportedOperationException。 */public V remove(Object key) {Iterator<Entry<K,V>> i = entrySet().iterator();Entry<K,V> correctEntry = null; //用于指向給定鍵值對應的映射關系//找到指定鍵的映射關系,并賦值給correctEntryif (key==null) {while (correctEntry==null && i.hasNext()) {Entry<K,V> e = i.next();if (e.getKey()==null)correctEntry = e;}} else {while (correctEntry==null && i.hasNext()) {Entry<K,V> e = i.next();if (key.equals(e.getKey()))correctEntry = e;}}V oldValue = null;if (correctEntry !=null) {oldValue = correctEntry.getValue(); //得到以前與key關聯的值i.remove(); //運用迭代器中的remove()方法來對得到的鍵值對項進行移除工作 }return oldValue;}//從指定Map中將所有映射關系<key,value>復制到此映射中public void putAll(Map<? extends K, ? extends V> m) {for (Map.Entry<? extends K, ? extends V> e : m.entrySet())put(e.getKey(), e.getValue());}//從此映射中移除所有映射關系public void clear() {entrySet().clear();}//用volatile修飾的變量,線程在每次使用變量的時候,都會讀取變量最后修改后的值transient volatile Set<K> keySet; //Map中key值的唯一性決定鍵值集合的視圖類型為Settransient volatile Collection<V> values; //Map中value值的可重復性決定值集合的視圖類型為Collection//返回此映射中包含的鍵的 Set視圖public Set<K> keySet() {if (keySet == null) {keySet = 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);}};}return keySet;}//返回此映射中包含的值的 Collection視圖public Collection<V> values() {if (values == null) {values = new AbstractCollection<V>() {public Iterator<V> iterator() {return new Iterator<V>() {private Iterator<Entry<K,V>> i = entrySet().iterator();public boolean hasNext() {return i.hasNext();}public V next() {return i.next().getValue(); //得到value值 }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 v) {return AbstractMap.this.containsValue(v);}};}return values;}//返回此映射中包含的映射關系的 Set 視圖public abstract Set<Entry<K,V>> entrySet();//比較指定對象與此映射的相等性public boolean equals(Object o) {//如果給定對象也是一個映射并且兩個映射表示相同的映射關系,則返回trueif (o == this)return true;//檢查指定的對象是否為映射關系if (!(o instanceof Map))return false;Map<?,?> m = (Map<?,?>) o; //強制類型轉換//檢查指定的對象是否是一個大小與此映射相等的映射if (m.size() != size())return false;//在此映射 entrySet()返回的collection上進行迭代,并檢查指定的映射是否包含此映射所包含的每個映射關系try {Iterator<Entry<K,V>> i = entrySet().iterator();while (i.hasNext()) {Entry<K,V> e = i.next();K key = e.getKey(); //此映射的key值V value = e.getValue(); //此映射的value值if (value == null) {if (!(m.get(key)==null && m.containsKey(key)))return false;} else {if (!value.equals(m.get(key)))return false;}}} catch (ClassCastException unused) {return false;} catch (NullPointerException unused) {return false;}return true;}//返回此映射的哈希值//Map的哈希碼被定義為該映射的 entrySet()視圖中每個條目的哈希碼之和。這確保了 m1.equals(m2)對于任意兩個映射m1和m2都意味著 m1.hashCode()==m2.hashCode()public int hashCode() {int h = 0;Iterator<Entry<K,V>> i = entrySet().iterator();while (i.hasNext())h += i.next().hashCode();return h;}//返回此映射的字符串表示形式:{key1=value1}, {key1=value1}, ...public String toString() {Iterator<Entry<K,V>> i = entrySet().iterator();if (! i.hasNext()) //Map為nullreturn "{}";StringBuilder sb = new StringBuilder();sb.append('{');for (;;) {Entry<K,V> e = i.next();K key = e.getKey();V value = e.getValue();sb.append(key == this ? "(this Map)" : key);sb.append('=');sb.append(value == this ? "(this Map)" : value);if (! i.hasNext())return sb.append('}').toString();sb.append(',').append(' ');}}//返回此 AbstractMap 實例的淺表副本:不復制鍵和值本身protected Object clone() throws CloneNotSupportedException {AbstractMap<?,?> result = (AbstractMap<?,?>)super.clone();result.keySet = null;result.values = null;return result;} } View Code

?

轉載于:https://www.cnblogs.com/CherishFX/p/4740113.html

總結

以上是生活随笔為你收集整理的jdk1.8.0_45源码解读——Map接口和AbstractMap抽象类的实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧美 亚洲 另类 激情 另类 | 蜜桃综合| 麻豆视频污| 亚洲精品中文字幕在线播放 | 亚洲熟区 | 一本久道久久综合 | 一卡二卡在线观看 | 国产白浆在线观看 | 亚洲高清在线一区 | 久久综合亚洲 | 国产日韩精品一区二区三区在线 | 国产熟妇另类久久久久 | 懂色av一区| aa视频网站 | 东北少妇高潮抽搐 | 国产一区色 | 鲁大师私人影院在线观看 | 亚洲av永久无码国产精品久久 | 精品国产乱码久久久久久1区2区 | 国产精品电影一区二区 | 日本熟妇乱子伦xxxx | 韩日免费av | 黄色美女视频网站 | 自拍偷自拍亚洲精品播放 | 丰满熟女人妻一区二区三 | 肥臀熟女一区二区三区 | 色婷婷婷婷 | 亚洲第一页在线观看 | 国产91综合一区在线观看 | 久操久热 | 色屁屁一区二区三区视频 | 亚洲精品高潮 | 日韩精品一区二区三区网站 | 欧美日韩精品一区二区三区蜜桃 | 国产91精选 | 日本免费www | 2019年中文字幕 | 日韩的一区二区 | 99精品国产一区二区 | 日本久操 | 少妇极品熟妇人妻无码 | 在线观看视频福利 | 国产无码精品合集 | 欧美日韩一级二级 | 人妻久久一区二区 | 97麻豆| 中文在线日韩 | 亚洲一区二区三区在线播放 | 亚洲特黄特色 | 少妇扒开粉嫩小泬视频 | 欧美视频在线观看一区 | 中文字字幕在线中文 | 一区二区激情 | 热99在线| 国精品一区二区三区 | 91av视频免费观看 | 日韩专区av | 成人激情小说网站 | 综合伊人av| 毛片动漫 | 成人区人妻精品一区二 | 日本888xxxx| av色成人| 国产区亚洲区 | 韩国精品一区 | 男人日女人免费视频 | 男人天堂免费视频 | 国产激情视频 | 天天综合天天 | 在线观看免费av网站 | 亚洲综合av一区 | 99热亚洲精品 | 成人亚洲一区二区 | 欧美国产一二三区 | 97在线公开视频 | 黄色日本视频 | 美国性生活大片 | 三女警花合力承欢猎艳都市h | 少妇一级淫片免费看 | www国产一区 | 老外黄色一级片 | 免费男女乱淫真视频免费播放 | 小sao货cao死你 | 影音先锋国产在线 | 国产男女在线 | 97超级碰碰人妻中文字幕 | 蜜桃传媒一区二区亚洲 | 黄色性视频网站 | 欧美极品一区二区三区 | 亲切的金子餐桌片段的金子 | 91视频免费播放 | 精品欧美一区二区三区在线观看 | 国产精品无码网站 | 秋霞福利影院 | 青青操免费在线视频 | 精品日韩制服无码久久久久久 | 青青草免费在线视频 | 色综合成人 | 亚洲精品在线免费观看视频 |