天天看點

java中的Map集合

大家好,又見面了,我是你們的朋友全棧君。

什麼是Map集合?

Map用于儲存具有映射關系的資料,Map集合裡儲存着兩組值,一組用于儲存Map的ley,另一組儲存着Map的value。

圖解

java中的Map集合

map集合的作用

和查字典類似,通過key找到對應的value,通過頁數找到對應的資訊。用學生類來說,key相當于學号,value對應name,age,sex等資訊。用這種對應關系友善查找。

Map和Set的關系

可以說關系是很密切了,雖然Map中存放的時鍵值對,Set中存放的是單個對象,但如果把value看做key的附庸,key在哪裡,value就在哪裡,這樣就可以像對待Set一樣來對待Map了。事實上,Map提供了一個Entry内部類來封裝key-value對,再計算Entry存儲時則隻考慮Entry封裝的key。

如果把Map集合裡的所有value放在一起來看,它們又類似于一個List,元素可以重複,每個元素可以根據索引來找,隻是Map中的索引不再是整數值,而是以另一個對象作為索引。

Map中的常用方法:

  • void clear()

    :删除該Map對象中所有鍵值對;
  • boolean containsKey(Object key)

    :查詢Map中是否包含指定的key值;
  • boolean containsValue(Object value)

    :查詢Map中是否包含一個或多個value;
  • Set entrySet()

    :傳回map中包含的鍵值對所組成的Set集合,每個集合都是Map.Entry對象。
  • Object get()

    :傳回指定key對應的value,如果不包含key則傳回null;
  • boolean isEmpty()

    :查詢該Map是否為空;
  • Set keySet()

    :傳回Map中所有key組成的集合;
  • Collection values()

    :傳回該Map裡所有value組成的Collection。
  • Object put(Object key,Object value)

    :添加一個鍵值對,如果集合中的key重複,則覆寫原來的鍵值對;
  • void putAll(Map m)

    :将Map中的鍵值對複制到本Map中;
  • Object remove(Object key)

    :删除指定的key對應的鍵值對,并傳回被删除鍵值對的value,如果不存在,則傳回null;
  • boolean remove(Object key,Object value)

    :删除指定鍵值對,删除成功傳回true;
  • int size()

    :傳回該Map裡的鍵值對個數;

内部類Entry

Map中包括一個内部類Entry,該類封裝一個鍵值對,常用方法:

  • Object getKey()

    :傳回該Entry裡包含的key值;
  • Object getvalue()

    :傳回該Entry裡包含的value值;
  • Object setValue(V value)

    :設定該Entry裡包含的value值,并設定新的value值。

執行個體:

HashMap<String, Integer> hm = new HashMap<>();

        //放入元素
        hm.put("Harry",23);
        hm.put("Jenny",24);
        hm.put("XiaoLi",20);

        System.out.println(hm);//{XiaoLi=20, Harry=23, Jenny=24}
        System.out.println(hm.keySet());//[XiaoLi, Harry, Jenny]
        System.out.println(hm.values());//[20, 23, 24]

        Set<Map.Entry<String, Integer>> entries = hm.entrySet();

        for (Map.Entry<String, Integer> entry : entries) {
            System.out.println(entry.getKey());
            System.out.println(entry.getValue());
        }           

複制

java8為Map新增的方法

  • Object compute(Object key,BiFurcation remappingFunction):

    使用remappingFunction根據原鍵值對計算一個新的value,隻要新value不為null,就覆寫原value;如果新value為null則删除該鍵值對,如果同時為null則不改變任何鍵值對,直接傳回null。
HashMap<String, Integer> hm = new HashMap<>();

        //放入元素
        hm.put("Harry",23);
        hm.put("Jenny",24);
        hm.put("XiaoLi",20);

        System.out.println(hm);//{XiaoLi=20, Harry=23, Jenny=24}
        hm.compute("Harry",(key,value)->(Integer)value+10);
        System.out.println(hm);//{XiaoLi=20, Harry=33, Jenny=24}           

複制

  • Object computeIfAbsent(Object key,Furcation mappingFunction):

    如果傳給該方法的key參數在Map中對應的value為null,則使用mappingFunction根據key計算一個新的結果,如果計算結果不為null,則計算結果覆寫原有的value,如果原Map原來不包含該Key,那麼該方法可能會添加一組鍵值對。
HashMap<String, Integer> hm = new HashMap<>();

        //放入元素
        hm.put("Harry",23);
        hm.put("Jenny",24);
        hm.put("XiaoLi",20);
        hm.put("LiMing",null);

        //指定key為null則計算結果作為value
        hm.computeIfAbsent("LiMing",(key)->10);
        System.out.println(hm);//{XiaoLi=20, Harry=23, Jenny=24, LiMing=10}

        //如果指定key本來不存在,則添加對應鍵值對
        hm.computeIfAbsent("XiaoHong",(key)->34);
        System.out.println(hm);//{XiaoLi=20, Harry=23, XiaoHong=34, Jenny=24, LiMing=10}           

複制

  • Object compute(Object key,BiFurcation remappingFunction):

    如果傳給該方法的key參數在Map中對應的value不為null,則通過計算得到新的鍵值對,如果計算結果不為null,則覆寫原來的value,如果計算結果為null,則删除原鍵值對。
hm.computeIfPresent("Harry",(key,value)->(Integer)value*(Integer)value);
        System.out.println(hm);
        //{XiaoLi=20, Harry=529, Jenny=24, LiMing=null}           

複制

  • void forEach(BiConsumer action)

    :周遊鍵值對。
HashMap<String, Integer> hm = new HashMap<>();

        //放入元素
        hm.put("Harry",23);
        hm.put("Jenny",24);
        hm.put("XiaoLi",20);
        hm.put("LiMing",null);
        
        hm.forEach((key,value)-> System.out.println(key+"->"+value));
        /*XiaoLi->20
        Harry->23
        Jenny->24
        LiMing->null*/           

複制

  • Object getOrDefault(Object key,V defaultValue)

    :擷取指定key對應的value,如果key不存在則傳回defaultValue;
System.out.println(hm.getOrDefault("Harry",33));//23           

複制

  • Object merge(Object key,Object value,BiFurcation remappingFunction)

    :該方法會先根據key參數擷取該Map中對應的value。如果擷取的value為null,則直接用傳入的value覆寫原有的value,如果擷取的value不為null,則使用remappingFunction函數根據原value、新value計算一個新的結果,并用得到的結果去覆寫原有的value。
HashMap<String, Integer> hm = new HashMap<>();

        //放入元素
        hm.put("Harry",23);
        hm.put("Jenny",24);
        hm.put("XiaoLi",20);
        hm.put("LiMing",null);

        hm.merge("LiMing",24,(key,value)->value+10);
        System.out.println(hm);//{XiaoLi=20, Harry=23, Jenny=24, LiMing=24}
        hm.merge("Harry",24,(key,value)->value+10);
        System.out.println(hm);//{XiaoLi=20, Harry=34, Jenny=24, LiMing=24}           

複制

  • Object putIfAbsent(Object key,Object value)

    :該方法會自動檢測指定key對應的value是否為null,如果為null,則用新value去替換原來的null值。
  • Object replace(Object key,Object value)

    :将key對應的value替換成新的value,如果key不存在則傳回null。
  • boolean replace(K key,V oldValue,V newValue)

    :将指定鍵值對的value替換成新的value,如果未找到則傳回false;
  • replaceAll(BiFunction Function)

    :使用BiFunction對原鍵值對執行計算,并将結果作為該鍵值對的value值。

java8改進的HashMap和Hashtable實作類

HashMap和Hashtable的關系完全類似于ArrayList和Vector的關系。

差別

  • Hashtable是線性安全的,HashMap是線性不安全的,是以後者效率更高。
  • Hashtable不允許使用null作為key和value,否則會引發異常,而HashMap可以;

和HashSet的關系

  • 與HashSet集合不能保證元素順序一樣,HashMap和Hashtable也不能保證鍵值對的順序。他們判斷兩個key相等的标準也是:兩個key通過equals方法比較傳回true,兩個key的hashCode值也相等。而判斷value值相等的标準:隻要兩個對象通過equals方法比較傳回true即可。
  • 不能修改集合中的key,否則程式再也無法準确通路到Map中被修改過的key。

LinkedHashMap實作類

和HashSet中的LinkedHashSet一樣,HashMap也有一個LinkedHashMap子類,使用雙向連結清單來維護鍵值對的次序,疊代順序和插入順序保持一緻。

使用Properties讀寫屬性檔案

Properties類是Hashtable類的子類,該對象在處理屬性檔案時特别友善。Properties類可以把Map對象和屬性檔案關聯起來,進而把Map對象的鍵值對寫入屬性檔案中,也可以把屬性檔案中的“屬性名=屬性值”加載到Map對象中。

Properties相當于一個key、value都是String類型的Map
  • String getProperty(String key)

    :擷取Properties中指定的屬性名對應的屬性值。
  • String getProperty(String key,String defaultValue)

    :和前一個方法相同,隻不過如果key不存在,則該方法指定預設值。
  • Object setProperty(String key,String value)

    :設定屬性值,類似于Hashtable的put方法;
  • void load(InputStream inStream)

    :從屬性檔案中加載鍵值對,把加載出來的鍵值對追加到Properties裡。
  • void store(OutputStream out,String comments)

    :将Properties中的鍵值對輸出到指定的屬性檔案中。

執行個體:

public static void main(String[] args) throws Exception {
        Properties props = new Properties();

        //向Properties中添加屬性
        props.setProperty("username","yeeku");
        props.setProperty("password","123456");

        //儲存到檔案中
        props.store(new FileOutputStream("a.ini"),"comment line");

        //建立一個Properties對象
        Properties props2 = new Properties();
        props2.setProperty("gender","male");
        //将檔案中的鍵值對追加到對象中
        props2.load(new FileInputStream("a.ini"));
        System.out.println(props2);//{password=123456, gender=male, username=yeeku}
    }           

複制

檔案内容

java中的Map集合

還可以把鍵值對以XML檔案的形式儲存起來,同樣可以從檔案中加載出來,用法與上述案例相同。

SortedMap接口和TreeMap實作類

正如Set接口派生出SortedSet子接口,Sorted接口有一個TreeSet實作類一樣,Map接口也派生出一個SortedMap子接口,SortedMap接口也有一個TreeMap實作類。

TreeMap就是一個紅黑樹資料結構,每個鍵值對作為紅黑樹的一個節點。存儲鍵值對時根據key對節點進行排序。可以保證所有鍵值對處于有序狀态。

和TreeSet一樣,TreeMap也有自然排序和定制排序兩種排序方式。

與TreeSet類似的是,TreeMap中提供了一系列根據key順序通路鍵值對的方法:

public static void main(String[] args) {
        TreeMap<String, Integer> stuTreeMap = new TreeMap<>(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                int num=o1.compareTo(o2);
                return num;
            }
        });


        stuTreeMap.put("LiMing",14);
        stuTreeMap.put("LiMing",24);
        stuTreeMap.put("Jenny",16);
        stuTreeMap.put("Denny",24);

        System.out.println(stuTreeMap);//{Denny=24, Jenny=16, LiMing=24}
        
        System.out.println(stuTreeMap.firstEntry());//Denny=24

    }           

複制

  • Map.Entry firstEntry():

    傳回該Map中最小的key所對應的鍵值對,如果Map為空則傳回null;
System.out.println(stuTreeMap.firstEntry());//Denny=24           

複制

  • Object firstKey()

    :傳回該Map中的最小key值,如果Map為空則傳回null;
  • Object lastKey()

    :傳回該Map中的最大key值,如果Map為空則傳回null;
  • Map.Entry higherEntry(Object key)

    :傳回該Map中位于key後一位的鍵值對;
  • Object higherKey(Object key)

    :傳回該Map中位于key後一位的key;
  • Map.Entry lowerEntry(Object key)

    :傳回該Map中位于key前一位的鍵值對;
  • Object lowererKey(Object key)

    :傳回該Map中位于key前一位的key;
  • NavigableMap tailMap(Object fromkey,boolean fromInclusive,Object toKey,boolean toInclusive)

    :傳回該Map的子Map,其key範圍從fromkey(是否包含取決于第二個參數)到toKey(是否包含取決于第四個參數)。

WeakHashMap實作類

WeakHashMap與HashMap的用法基本相似,差別在于HashMap的key保留了對實際對象的強引用,這意味着隻要該對象不銷毀,該HashMap的所有key所引用的對象就不會被垃圾回收,HashMap也不會自動删除這些key所對應的鍵值對,但WeakHashMap的key隻保留了對實際對象的弱引用,這意味着如果WeakHashMap對象的key所引用的對象沒有被其他強引用變量所引用,則這些key所引用的對象可能被垃圾回收,WeakHashMap也可能自動删除這些key對應的鍵值對。

IdentityHashMap實作類

這個類的實作機制與HashMap基本相似,但它在處理兩個key相等時比較獨特:在IdentityHashMap中,當且僅當兩個key嚴格相等(key1==key2)時,IdentityHashMap才認為兩個key相等,對于普通的HashMap而言,隻要key1和key2通過equals方法比較傳回true,且它們的hashcode相等即可。

IdentityHashMap map = new IdentityHashMap<>();

        map.put(new String("國文"), 89);
        map.put(new String("國文"), 90);

        map.put("java",70);
        map.put("java",71);
        System.out.println(map);//{java=71, 國文=90, 國文=89}           

複制

前面是兩個對象雖然通過equal方法比較是相等的,但是通過

==

比較不相等,後面兩個字元串在常量池中同一位置,是以使用

==

判斷相等。

釋出者:全棧程式員棧長,轉載請注明出處:https://javaforall.cn/139179.html原文連結:https://javaforall.cn