10_07【Java】Map集合详述
如果想要存儲具有映射關系的數據,那么就需要使用Map集合了。Map集合由Map接口和Map接口的實現類組成。
一、Map接口概述
1、Map接口是什么?
Map是一個以鍵值對存儲的接口,也就是將鍵映射到值的對象。映射不能包含重復的鍵,每個鍵最多可以映射到一個值,并且鍵不能重復,不能為空。總結來說:Map存儲的是鍵值對,鍵唯一,一個鍵對應唯一的一個值。
Map接口雖然沒有繼承Collection接口,但是提供了key到value的映射關系。
Interface Map<K,V>- K:映射的key
- V:映射的值
Map接口提供了三個集合視圖,允許將Map的內容作為單獨的一組鍵、單獨的一組值,或者是一組鍵值映射。映射的順序被定義為映射集合視圖上的迭代器返回元素的順序。對一些類中元素的順序進行了設置,比如TreeMap;而HashMap則不需要進行元素順序保證。
2、Map接口的特點:
Map 接口中鍵和值一一映射,可以通過鍵來獲取值。
- 給定一個鍵和一個值,你可以將該值存儲在一個 Map 對象。之后,你可以通過鍵來訪問對應的值。
- 當訪問的值不存在的時候,方法就會拋出一個 NoSuchElementException 異常。
- 當對象的類型和 Map 里元素類型不兼容的時候,就會拋出一個 ClassCastException 異常。
- 當在不允許使用 Null 對象的 Map 中使用 Null 對象,會拋出一個 NullPointerException 異常。
- 當嘗試修改一個只讀的 Map 時,會拋出一個 UnsupportedOperationException 異常。
3、Map的子接口及其繼承關系
(1)Map接口在java.util中的位置
(2)Map子接口及繼承關系
Map的所有子接口有:
Bindings, ConcurrentMap<K,V>, ConcurrentNavigableMap<K,V>, LogicalMessageContext, MessageContext, NavigableMap<K,V>, SOAPMessageContext, SortedMap<K,V>
其中,常用的子接口包括SortedMap和NavigebleMap,他們的繼承關系如下圖:
二、Map接口的方法
1、Map的所有方法
| clear() | void | 從該映射中刪除所有映射(可選操作) |
| compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) | defaultV | 嘗試計算指定鍵及其當前映射值的映射(如果沒有當前映射,則為null)。 |
| computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction) | defaultV | 如果指定的鍵尚未與某個值關聯(或映射為null),則嘗試使用給定的映射函數計算其值并將其輸入到該映射中,除非為null。 |
| computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) | defaultV | 如果指定鍵的值存在且非空,則嘗試計算給定鍵及其當前映射值的新映射。 |
| containsKey(Object key) | boolean | 如果此映射包含指定鍵的映射,則返回true。 |
| containsValue(Object value) | boolean | 如果此映射將一個或多個鍵映射到指定的值,則返回true。 |
| entrySet() | Set<Map.Entry<K,V>> | 返回此映射中包含的映射的集合視圖。 |
| equals(Object o) | boolean | 比較指定的對象與此映射是否相等。 |
| forEach(BiConsumer<? super K,? super V> action) | defaultvoid | 對映射中的每個條目執行給定的操作,直到所有條目都已處理或操作拋出異常為止。 |
| get(Object key) | V | 返回指定鍵映射到的值,如果該映射不包含該鍵的映射,則返回null。 |
| getOrDefault(Object key, V defaultValue) | defaultV | 返回指定鍵映射到的值,如果該映射不包含該鍵的映射,則返回defaultValue。 |
| hashCode() | int | 返回此映射的哈希碼值。 |
| isEmpty() | boolean | 如果該映射不包含鍵-值映射,則返回true。 |
| keySet() | Set<K> | 返回此映射中包含的鍵的集合視圖。 |
| merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction) | defaultV | 如果指定的鍵尚未與值關聯或與null關聯,則將其與給定的非空值關聯 |
| put(K key, V value) | V | 將此映射中的指定值與指定鍵關聯(可選操作)。 |
| putAll(Map<? extends K,? extends V> m) | void | 將指定映射中的所有映射復制到此映射(可選操作)。 |
| putIfAbsent(K key, V value) | defaultV | 如果指定的鍵尚未與值關聯(或映射為null),則將其與給定值關聯并返回null,否則返回當前值。 |
| remove(Object key) | V | 如果密鑰存在,則從該映射中刪除該密鑰的映射(可選操作)。 |
| remove(Object key, Object value) | defaultboolean | 僅當指定鍵項當前映射到指定值時才刪除該項。 |
| replace(K key, V value) | defaultV | 86/5000 僅在當前映射到某個值時替換指定鍵的條目。 |
| replace(K key, V oldValue, V newValue) | defaultboolean | 僅在當前映射到指定值時替換指定鍵的條目。 |
| replaceAll(BiFunction<? super K,? super V,? extends V> function) | defaultvoid | 將每個條目的值替換為對該條目調用給定函數的結果,直到處理完所有條目或該函數拋出異常。 |
| size() | int | 返回此映射中鍵-值映射的數目。如果映射包含超過整數。MAX_VALUE元素,返回整數.MAX_VALUE。 |
| values() | Collection<V> | 返回此映射中包含的值的集合視圖。 |
2、Map常用方法
實例1:Map接口常用方法應用
import java.util.*;public class MapTest {public static void main(String[] args) {// TODO Auto-generated method stubMap<String,String> map = new HashMap<>();map.put("01","Tom");map.put("02","Bob");map.put("05","Henry");map.put("04","Lily");map.put("07","Jack");map.put("010","Tony");Map<String,String> map2 = new TreeMap<>();map2.put("01","Tom");map2.put("02","Bob");map2.put("05","Henry");map2.put("04","Lily");map2.put("07","Jack");map2.put("010","Tony");System.out.println("map:"+map);System.out.println("map2:"+map2);// 返回當前數據個數int size = map.size();System.out.println("map當前鍵值對組數:"+size);// 是否為空boolean isEmpty = map.isEmpty();System.out.println("map是否為空?"+isEmpty);// 判斷是否包含指定的key,這里用到了key的equals方法,所以key必須實現它boolean containsKey= map.containsKey("08");System.out.println("判斷map是否包含指定的key:"+containsKey);// 判斷是否有key保存的值是value,這也基于equals方法boolean containsValue = map.containsValue("Lily");System.out.println("判斷map是否包含指定的value:"+containsValue);// 通過key獲取對應的value值System.out.println("通過key獲取map對應的value值:"+map.get("03"));// 存入key-valuemap.put("11", "Sam");map2.put("11", "Sam");System.out.println("現在的map:"+map);// 返回所有的key至Set集合中,因為key是不可重的,Set也是不可重的System.out.println("返回map所有的key至Set集合中:"+map.keySet());// 返回所有的valuesSystem.out.println("返回map返回所有的values至Set集合中:"+map.values());// 返回key-value對到Set中System.out.println("返回mapkey-value對至Set集合中:"+map.entrySet());// 希望我們實現equals和hashCodeSystem.out.println("map的hashocode值:"+map.hashCode());System.out.println("map2的hashocode值:"+map2.hashCode());System.out.println("判斷map和map2是否相同:"+map.equals(map2));// 移除一個key-value對map.remove("05");map2.remove("05");System.out.println("移除key為05的鍵值對后的map"+map);// 清空map.clear();System.out.println("移除所有鍵值對后的map"+map);}} ConsoleLmap:{01=Tom, 02=Bob, 04=Lily, 05=Henry, 07=Jack, 010=Tony} map2:{01=Tom, 010=Tony, 02=Bob, 04=Lily, 05=Henry, 07=Jack} map當前鍵值對組數:6 map是否為空?false 判斷map是否包含指定的key:false 判斷map是否包含指定的value:true 通過key獲取map對應的value值:null 現在的map:{11=Sam, 01=Tom, 02=Bob, 04=Lily, 05=Henry, 07=Jack, 010=Tony} 返回map所有的key至Set集合中:[11, 01, 02, 04, 05, 07, 010] 返回map返回所有的values至Set集合中:[Sam, Tom, Bob, Lily, Henry, Jack, Tony] 返回mapkey-value對至Set集合中:[11=Sam, 01=Tom, 02=Bob, 04=Lily, 05=Henry, 07=Jack, 010=Tony] map的hashocode值:77101877 map2的hashocode值:77101877 判斷map和map2是否相同:true 移除key為05的鍵值對后的map{11=Sam, 01=Tom, 02=Bob, 04=Lily, 07=Jack, 010=Tony} 移除所有鍵值對后的map:{}三、Map接口的所有實現類
1、Map接口的所有實現類
| AbstractMap | 該類提供Map接口的基本實現,以最小化實現該接口所需的工作。要實現不可修改的映射,程序員只需擴展這個類并為entrySet方法提供一個實現,該方法返回映射的集合視圖。通常,返回的集合將依次在AbstractSet上實現。這個集合不應該支持添加或刪除方法,它的迭代器也不應該支持刪除方法。要實現可修改的映射,程序員必須另外重寫這個類的put方法(否則會拋出UnsupportedOperationException), entrySet().iterator()返回的迭代器必須另外實現它的remove方法。按照map接口規范中的建議,程序員通常應該提供一個void(無參數)和映射構造函數。該類中每個非抽象方法的文檔都詳細描述了其實現。如果正在實現的映射允許更有效的實現,則這些方法中的每一個都可能被覆蓋。該類是Java Collections框架的成員。 |
| Attributes | 該屬性類將清單屬性名稱映射到關聯的字符串值。有效的屬性名不區分大小寫,只能使用集合[0-9a-zA-Z_-]中的ASCII字符,長度不能超過70個字符。屬性值可以包含任何字符,并在寫入輸出流時采用utf8編碼。有關有效屬性名稱和值的更多信息,請參見JAR File Specification。 |
| AuthProvider | 該類為提供程序定義登錄和注銷方法。雖然調用方可以直接調用登錄,但是如果提供者確定必須在某些操作之前執行登錄,它也可以代表調用方調用登錄。 |
| ConcurrentHashMap | 該類繼承ConcurrentMap < K、V > 和NavigableMap < K、V >類。ConcurrentMap支持NavigableMap操作,并且遞歸地支持它的可導航子映射。該接口是Java Collection框架的成員。 |
| ConcurrentSkipListMap | 該類繼承AbstractMap < K、V >類。實現ConcurrentNavigableMap, Cloneable, Serializable接口。ConcurrentSkipListMap是一個可擴展的并發ConcurrentNavigableMap。映射根據其鍵的自然順序進行排序,或者通過在映射創建時提供的比較器進行排序,具體取決于使用的構造函數。 這個類實現了跳碼器的一個并發變體,使containsKey、get、put和remove操作及其變的時間復雜度預期為log(n)。插入、刪除、更新和訪問操作安全地由多個線程并發執行。迭代器和分塊器是弱一致的。升序鍵排序視圖及其迭代器比降序視圖更快。類中的方法返回的條目對及其視圖表示生成映射時的快照。它們不支持Entry.setValue方法。(使用put、putIfAbsent或replace可以更改關聯映射中的映射,具體取決于程序需要的效果)。 與大多數集合不同,由于這些映射的異步本質,size方法不是常量時間操作。確定當前元素數量需要遍歷元素,因此如果在遍歷期間修改了這個集合,可能會報告不準確的結果。 此外,不能保證批量操作putAll、equals、toArray、containsValue和clear會自動執行。例如,與putAll操作并發操作的迭代器可能只查看添加的部分元素。 這個類及其視圖和迭代器實現了映射和迭代器接口的所有可選方法。與大多數其他并發集合一樣,這個類不允許使用空鍵或值,因為一些空返回值無法可靠地與缺少元素區分開來。該類是Java Collections框架的成員。 |
| EnumMap | 繼承AbstractMap < K、V >類,實現了Serializable,Cloneable接口。用于枚舉類型鍵的專用映射實現。枚舉映射中的所有鍵必須來自創建映射時顯式或隱式指定的單個枚舉類型。枚舉映射在內部使用緊湊和有效的數組表示。枚舉映射按照鍵的自然順序(聲明枚舉常量的順序)維護。這反映在集合視圖返回的迭代器中(keySet()、entrySet()和values())。 集合視圖返回的迭代器是弱一致性的:它們永遠不會拋出ConcurrentModificationException,而且它們可能會顯示在迭代過程中對映射進行的任何修改的效果。該類不允許使用空鍵,但允許使用空值。嘗試插入空鍵會拋出NullPointerException。與大多數集合實現一樣,EnumMap是不同步的,如果多個線程并發地訪問一個枚舉映射,并且至少有一個線程修改了映射,那么它應該在外部同步。這通常是通過在自然封裝enum映射的對象上同步來實現的。如果不存在這樣的對象,則應該使用Collections.synchronizedMap(java.util.Map< K、V >)方法。這最好在創建時完成,以防止意外的不同步訪問。所有基本操作都在固定時間內執行。它們可能(盡管不能保證)比對應的HashMap更快。該類是Java Collections框架的成員。 |
| HashMap | 基于哈希表實現的映射接口。此實現提供了所有可選映射操作,并允許空值和空鍵。(HashMap類大致相當于Hashtable,只是它是不同步的,并且允許空值。)這個類不能保證映射的順序;特別是,它不能保證順序隨時間保持不變。該類是Java Collections框架的成員。 |
| Hashtable | 該類實現了一個哈希表,它將鍵映射到值。任何非空對象都可以用作鍵或值。要成功地從散列表中存儲和檢索對象,用作鍵的對象必須實現hashCode方法和equals方法。該類是Java Collections框架的成員。 |
| IdentityHashMap | 繼承AbstractMap < K、V >類,實現Map, Serializable, Cloneable接口。這個類使用散列表實現映射接口,在比較鍵(和值)時使用引用相等性代替對象相等性。換句話說,在一個IdentityHashMap中,當且僅當(k1==k2)時,兩個鍵k1和k2被認為是相等的。雖然這個類實現了Map接口,但它有意違反了Map的一般約定(該約定要求在比較對象時使用equals方法),因此它不是通用的映射實現。這個類僅設計用于需要引用相等語義的極少數情況。該類是Java Collections框架的成員。 |
| LinkedHashMap | 該類繼承HashMap類,實現了Map接口。是哈希表和鏈表實現的映射接口,具有可預測的迭代順序。這個實現與HashMap的不同之處在于,它維護一個貫穿其所有條目的雙鏈列表。這個鏈表定義了迭代順序,這通常是鍵插入到映射中的順序(插入順序)。注意,如果一個鍵被重新插入到映射中,插入順序不會受到影響。(如果調用m.put(k, v),那么在調用之前m. containskey (k)將返回true時,密鑰k將重新插入映射m中)。該類是Java Collections框架的成員。 |
| PrinterStateReasons | 繼承HashMap<PrinterStateReason,Severity> 類,實現 PrintServiceAttributePrinterStateReasons接口。是一個打印屬性類,它是一組枚舉值,提供關于打印機當前狀態的附加信息,即增加打印機的PrinterState屬性值的信息。 |
| Properties | 繼承Hashtable <Object,object>類。Properties類表示一組持久的屬性。屬性可以保存到流中,也可以從流中加載。屬性列表中的每個鍵及其對應值都是一個字符串。屬性列表可以包含另一個屬性列表作為它的“默認值”;如果在原始屬性列表中沒有找到屬性鍵,則搜索第二個屬性列表。 |
| Provider | 是一個public修飾的抽象類。繼承Properties類,這個類表示Java安全性API的“提供程序”,其中提供程序實現Java安全性的部分或所有部分。提供者可能實現的服務包括:算法(如DSA、RSA、MD5或SHA-1);密鑰生成、轉換和管理功能(例如針對特定于算法的密鑰)。 每個提供程序都有一個名稱和版本號,并在安裝它的每個運行時中進行配置。 |
| RenderingHints | 繼承Object類,實現了Map<Object,Object>,Cloneable接口。RenderingHints類定義并管理鍵和相關值的集合,這些值允許應用程序為執行呈現和圖像操作服務的其他類所使用的算法的選擇提供輸入。Graphics2D類以及實現BufferedImageOp和RasterOp的類都提供了方法來獲取或設置RenderingHints鍵及其關聯值的單個或組。當這些實現執行任何渲染或圖像處理操作時,它們應該檢查調用者所請求的任何渲染函數的值,并相應地調整所使用的算法,并盡其所能。 |
| SimpleBindings | 繼承Object類,實現了Bindings接口。由HashMap或其他指定映射支持的簡單綁定實現。 |
| TabularDataSupport | 繼承Object類,實現了TabularData, Map<Object,Object>, Cloneable, Serializable接口。TabularDataSupport類是開放數據類,它實現了TabularData和Map接口,并且在內部基于散列映射數據結構。 |
| TreeMap | 繼承AbstractMap<K,V>類,實現了NavigableMap<K,V>, Cloneable, Serializable接口。基于紅黑樹的NavigableMap實現。映射根據其鍵的自然順序進行排序,或者通過在映射創建時提供的比較器進行排序,具體取決于使用的構造函數。這個實現為containsKey、get、put和remove操作提供了可保證的log(n)時間成本。算法是對Cormen, Leiserson和Rivest的《算法導論》中那些算法的改編。與任何排序映射一樣,樹映射維護的順序,以及無論是否提供顯式比較器,如果這個排序映射要正確實現map接口,則必須與equals保持一致。這是因為映射接口是根據equals操作定義的,但是排序映射使用它的compareTo(或compare)方法執行所有鍵比較,所以從排序映射的角度來看,這個方法認為相等的兩個鍵是相等的。TreeMap不是線程安全的。該類是Java Collections框架的成員。 |
| UIDefaults | 繼承Hashtable<Object,Object>類,Swing組件的默認值表。應用程序可以通過UIManager設置/獲取默認值。需要注意:這個類的序列化對象將與未來的Swing版本不兼容。當前的序列化支持適用于運行相同版本Swing的應用程序之間的短期存儲或RMI。從1.4開始,對所有JavaBeans?的長期存儲的支持已經添加到java.bean包。 |
| WeakHashMap | 繼承AbstractMap<K,V>類,實現了Map<K,V>接口。基于哈希表的Map接口實現,具有弱鍵。當WeakHashMap中的一個條目的鍵不再正常使用時,它將自動被刪除。更準確地說,給定鍵的映射的存在不會阻止該鍵被垃圾收集器丟棄。當一個鍵被丟棄時,它的條目將有效地從映射中刪除,因此這個類的行為與其他映射實現略有不同。 |
2、Map接口常用實現類繼承關系
Map接口最常用的實現類主要是TreeMap、HashMap。其繼承關系如下:
總結
以上是生活随笔為你收集整理的10_07【Java】Map集合详述的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Intellij Error:java:
- 下一篇: 9月8日,直播抽奖:涂鸦智能带您掘金千亿