欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java HashMap在遍歷時(shí)刪除元素的實(shí)現(xiàn)

 更新時(shí)間:2023年12月25日 15:11:38   作者:心流時(shí)間  
本文主要介紹了Java HashMap在遍歷時(shí)刪除元素的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

1. HashMap數(shù)據(jù)結(jié)構(gòu)

jdk是1.8版本

HashMap 線程不安全
ConcurrentHashMap 線程安全

1.1 數(shù)組+單向鏈表+紅黑樹

元素放入hashmap中,放入node節(jié)點(diǎn)中,nodel節(jié)點(diǎn)有四個(gè)字段key value next hash,當(dāng)兩個(gè)元素的key通過hash算法得到的hash值相同時(shí)就會(huì)存入單向鏈表中。hashmap初始值是16,負(fù)載因子是0.75,得到閾值是12,當(dāng)元素超過12就會(huì)擴(kuò)容,當(dāng)數(shù)組長(zhǎng)度超過64并且單向鏈表長(zhǎng)度超過8就會(huì)將單向鏈表轉(zhuǎn)為紅黑樹,當(dāng)紅黑樹數(shù)據(jù)量小于6就會(huì)再轉(zhuǎn)為單向鏈表

jdk1.8 之前 HashMap 由 數(shù)組 + 鏈表 組成,數(shù)組是 HashMap 的主體,鏈表則是主要為了解決哈希沖突(兩個(gè)對(duì)象調(diào)用的 hashCode 方法計(jì)算的哈希值經(jīng)哈希函數(shù)算出來的地址被別的元素占用)而存在的(“拉鏈法”解決沖突)。jdk1.8 以后在解決哈希沖突時(shí)有了較大的變化,當(dāng)鏈表長(zhǎng)度大于閾值(或者紅黑樹的邊界值,默認(rèn)為 8 )并且當(dāng)前數(shù)組的長(zhǎng)度大于 64 時(shí),此時(shí)此索引位置上的所有數(shù)據(jù)改為使用紅黑樹存儲(chǔ)。

在這里插入圖片描述

1.2 指定初始容量,省去多次擴(kuò)容步驟

實(shí)際工作中對(duì)HashMap數(shù)據(jù)結(jié)構(gòu)的關(guān)注點(diǎn),我們可以放在擴(kuò)容上;
HashMap初始容量是16,當(dāng)大于這個(gè)值,就會(huì)擴(kuò)容,每次都是擴(kuò)大成原來的兩倍;
所以,如果我們可以估算出我們的map需要多大的容量,在初始化的時(shí)候直接指定初始容量值,這樣就省略了HashMap一次次擴(kuò)容的步驟

1.3 獲取map內(nèi)容:Map.Entry

Map.Entry是Java中Map接口的一個(gè)內(nèi)部接口,用于表示Map中的一個(gè)實(shí)體,即一個(gè)鍵值對(duì)(key-value對(duì))。它是一個(gè)泛型接口,定義為Entry<K,V>,其中K表示鍵的類型,V表示值的類型。

你可以使用Map.Entry來遍歷Map集合,并獲取每個(gè)鍵值對(duì)的鍵和值。下面是一個(gè)示例代碼:

import java.util.HashMap;
import java.util.Map;

public class MapEntryExample {
    public static void main(String[] args) {
        Map<Integer, String> maps = new HashMap<>();
        maps.put(3, "張飛");
        maps.put(2, "關(guān)羽");
        maps.put(4, "趙云");
        maps.put(1, "劉備");
        maps.put(5, "馬超");

        for (Map.Entry<Integer, String> entry : maps.entrySet()) {
            System.out.println("key=" + entry.getKey() + " value=" + entry.getValue());
        }
    }
}
這段代碼會(huì)輸出Map中每個(gè)鍵值對(duì)的鍵和值:

key=1 value=劉備
key=2 value=關(guān)羽
key=3 value=張飛
key=4 value=趙云
key=5 value=馬超
通過使用Map.Entry,你可以方便地遍歷Map集合并獲取每個(gè)鍵值對(duì)的鍵和值。

2. 遍歷集合時(shí)刪除元素

遍歷集合時(shí)刪除元素這種場(chǎng)景建議用迭代器處理 或者 再新建一個(gè)集合進(jìn)行存儲(chǔ)

    public static void main(String[] args) {
        Map&lt;Integer, String&gt; stuMap = new HashMap&lt;&gt;();
        stuMap.put(1, "xlsj");
        stuMap.put(2, "xinliushijian");
        stuMap.put(3, "心流時(shí)間");

        // A: entrySet()、keySet()、values()方法作用
        // key:value 集合
        Set&lt;Map.Entry&lt;Integer, String&gt;&gt; stuEntrySet = stuMap.entrySet();
        // key 集合
        Set&lt;Integer&gt; stuKeySet = stuMap.keySet();
        // value 集合
        Collection&lt;String&gt; stuValues = stuMap.values();

        System.out.println(stuEntrySet); // [1=xlsj, 2=xinliushijian, 3=心流時(shí)間]
        System.out.println(stuKeySet); // [1, 2, 3]
        System.out.println(stuValues); // [xlsj, xinliushijian, 心流時(shí)間]


        // B: 遍歷集合時(shí)刪除元素, 普通for循環(huán)、迭代器不會(huì)報(bào)錯(cuò),其他會(huì)報(bào)錯(cuò),增強(qiáng)for循環(huán)其實(shí)也是用到迭代器,
        // 集合遍歷時(shí)不可以刪除元素,而迭代器可以
        // 報(bào)錯(cuò)原因如下modCount != expectedModCount
/*        final HashMap.Node&lt;K,V&gt; nextNode() {
            HashMap.Node&lt;K,V&gt;[] t;
            HashMap.Node&lt;K,V&gt; e = next;
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            if (e == null)
                throw new NoSuchElementException();
            if ((next = (current = e).next) == null &amp;&amp; (t = table) != null) {
                do {} while (index &lt; t.length &amp;&amp; (next = t[index++]) == null);
            }
            return e;
        }*/
        

        // 1.普通for循環(huán)遍歷時(shí)可以刪除元素
        for (int i = 0; i &lt; stuKeySet.size(); i++) {
            if (i == 2) {
                stuKeySet.remove(i);
            }
        }

        // 2.for增強(qiáng)循環(huán)遍歷時(shí)刪除元素報(bào)異常:Exception in thread "main" java.util.ConcurrentModificationException
        for (int i : stuKeySet) {
            if (i == 2) {
                stuKeySet.remove(i);
            }
        }

        // 3.forEach循環(huán)遍歷時(shí)刪除元素報(bào)異常:Exception in thread "main" java.util.ConcurrentModificationException
        stuMap.forEach((k, v) -&gt; {
            if (k == 2) {
                stuKeySet.remove(k);
            }
        });

        // 4.stream forEach循環(huán)遍歷時(shí)刪除元素報(bào)異常:Exception in thread "main" java.util.ConcurrentModificationException
        stuKeySet.stream().forEach(k -&gt; {
            if (k == 2) {
                stuKeySet.remove(k);
            }
        });

        // 5.迭代器遍歷時(shí)可以刪除元素
        Iterator integers = stuEntrySet.iterator();
        while (integers.hasNext()) {
            Map.Entry&lt;Integer, String&gt; entry = (Map.Entry&lt;Integer, String&gt;) integers.next();
            System.out.println(entry.getKey());
            if (entry.getKey() == 2) {
                integers.remove();
            }

        }

        System.out.println(stuMap);
    }

3. computeIfAbsent()方法

key不存在或者value為null時(shí),使用put給定的值

    public static void main(String[] args) {
        Map<String, List<String>> map = new HashMap<>();
        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        map.put("xin", list);
        map.put("xi", new ArrayList<>());
        map.put("x", null);

        // jing這個(gè)key不存在或者對(duì)應(yīng)的value不存在,則put給的值
        List<String> list1 = map.computeIfAbsent("jing",h -> Arrays.asList(new String[]{"DE", "BU", "DE"}));
        List<String> list2 = map.computeIfAbsent("xin",h -> Arrays.asList(new String[]{"DE", "BU", "DE"}));
        List<String> list3 = map.computeIfAbsent("xi",h -> Arrays.asList(new String[]{"DE", "BU", "DE"}));
        List<String> list4 = map.computeIfAbsent("x",h -> Arrays.asList(new String[]{"DE", "BU", "DE"}));
        System.out.println(list1);
        System.out.println(list2);
        System.out.println(list3);
        System.out.println(list4);
        System.out.println("---------------jing--------------");
        System.out.println(map.get("jing"));

        map.putIfAbsent("jing1", Arrays.asList(new String[]{"DE1", "BU1", "DE1"}));
        System.out.println("---------------jing1--------------");
        System.out.println(map.get("jing1"));
    }

打印

[DE, BU, DE]
[a, b, c]
[]
[DE, BU, DE]
---------------jing--------------
[DE, BU, DE]
---------------jing1--------------
[DE1, BU1, DE1]

到此這篇關(guān)于Java HashMap在遍歷時(shí)刪除元素的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Java HashMap遍歷時(shí)刪除元素內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

最新評(píng)論