国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

為什么阿里不推薦使用 keySet() 遍歷HashMap?

開發 前端
HashMap相信所有學Java的都一定不會感到陌生,作為一個非常重用且非常實用的Java提供的容器,它在我們的代碼里面隨處可見。因此遍歷操作也是我們經常會使用到的。

HashMap相信所有學Java的都一定不會感到陌生,作為一個非常重用且非常實用的Java提供的容器,它在我們的代碼里面隨處可見。因此遍歷操作也是我們經常會使用到的。HashMap的遍歷方式現如今有非常多種:

  1. 使用迭代器(Iterator)。
  2. 使用 keySet() 獲取鍵的集合,然后通過增強的 for 循環遍歷鍵。
  3. 使用 entrySet() 獲取鍵值對的集合,然后通過增強的 for 循環遍歷鍵值對。
  4. 使用 Java 8+ 的 Lambda 表達式和流。

以上遍歷方式的孰優孰劣,在《阿里巴巴開發手冊》中寫道:

圖片圖片

這里推薦使用的是entrySet進行遍歷,在Java8中推薦使用Map.forEach()。給出的理由是遍歷次數上的不同。

  1. keySet遍歷,需要經過兩次遍歷。
  2. entrySet遍歷,只需要一次遍歷。

其中keySet遍歷了兩次,一次是轉為Iterator對象,另一次是從hashMap中取出key所對應的value。

其中后面一段話很好理解,但是前面這句話卻有點繞,為什么轉換成了Iterator遍歷了一次?

我查閱了各個平臺對HashMap的遍歷,其中都沒有或者原封不動的照搬上句話。(當然也可能是我沒有查閱到靠譜的文章,歡迎指正)

keySet如何遍歷了兩次

我們首先寫一段代碼,使用keySet遍歷Map。

public class Test {
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("k1", "v1");
        map.put("k2", "v2");
        map.put("k3", "v3");
        for (String key : map.keySet()) {
            String value = map.get(key);
            System.out.println(key + ":" + value);
        }
    }

}

運行結果顯而易見的是

k1:v1
k2:v2
k3:v3

兩次遍歷,第一次遍歷所描述的是轉為Iterator對象我們好像沒有從代碼中看見,我們看到的后面所描述的遍歷,關注公眾號:碼猿技術專欄,回復關鍵詞:1111 獲取阿里內部Java性能調優手冊!也就是遍歷map,keySet()所返回的Set集合中的key,然后去HashMap中拿取value的。

Iterator對象呢?如何遍歷轉換為Iterator對象的呢?

首先我們這種遍歷方式大家都應該知道是叫:增強for循環,for-each

這是一種Java的語法糖~。

我們可以通過反編譯,或者直接通過Idea在class文件中查看對應的Class文件

圖片圖片

public class Test {
    public Test() {
    }

    public static void main(String[] args) {
        Map<String, String> map = new HashMap();
        map.put("k1", "v1");
        map.put("k2", "v2");
        map.put("k3", "v3");
        Iterator var2 = map.keySet().iterator();

        while(var2.hasNext()) {
            String key = (String)var2.next();
            String value = (String)map.get(key);
            System.out.println(key + ":" + value);
        }

    }
}

和我們編寫的是存在差異的,其中我們可以看到其中通過map.keySet().iterator()獲取到了我們所需要看見的Iterator對象。

那么它又是怎么轉換成的呢?為什么需要遍歷呢?我們查看iterator()方法

1. iterator()

圖片圖片

發現是Set定義的一個接口。返回此集合中元素的迭代器

2. HashMap.KeySet#iterator()

我們查看HashMap中keySet類對該方法的實現。

圖片圖片

圖片圖片

final class KeySet extends AbstractSet<K> {
    public final int size()                 { return size; }
    public final void clear()               { HashMap.this.clear(); }
    public final Iterator<K> iterator()     { returnnew KeyIterator(); }
    public final boolean contains(Object o) { return containsKey(o); }
    public final boolean remove(Object key) {
        return removeNode(hash(key), key, null, false, true) != null;
    }
    public final Spliterator<K> spliterator() {
        returnnew KeySpliterator<>(HashMap.this, 0, -1, 0, 0);
    }
    public final void forEach(Consumer<? super K> action) {
        Node<K,V>[] tab;
        if (action == null)
            thrownew NullPointerException();
        if (size > 0 && (tab = table) != null) {
            int mc = modCount;
            for (int i = 0; i < tab.length; ++i) {
                for (Node<K,V> e = tab[i]; e != null; e = e.next)
                    action.accept(e.key);
            }
            if (modCount != mc)
                thrownew ConcurrentModificationException();
        }
    }
}

其中的iterator()方法返回的是一個KeyIterator對象,那么究竟是在哪里進行了遍歷呢?我們接著往下看去。

3. HashMap.KeyIterator

圖片圖片

final class KeyIterator extends HashIterator
    implements Iterator<K> {
    public final K next() { return nextNode().key; }
}

這個類也很簡單:

  1. 繼承了HashIterator類。
  2. 實現了Iterator接口。
  3. 一個next()方法。

還是沒有看見哪里進行了遍歷,那么我們繼續查看HashIterator類

4. HashMap.HashIterator

圖片圖片

abstract class HashIterator {
    Node<K,V> next;        // next entry to return
    Node<K,V> current;     // current entry
    int expectedModCount;  // for fast-fail
    int index;             // current slot

    HashIterator() {
        expectedModCount = modCount;
        Node<K,V>[] t = table;
        current = next = null;
        index = 0;
        if (t != null && size > 0) { // advance to first entry
            do {} while (index < t.length && (next = t[index++]) == null);
        }
    }

    public final boolean hasNext() {
        return next != null;
    }

    final Node<K,V> nextNode() {
        Node<K,V>[] t;
        Node<K,V> e = next;
        if (modCount != expectedModCount)
            thrownew ConcurrentModificationException();
        if (e == null)
            thrownew NoSuchElementException();
        if ((next = (current = e).next) == null && (t = table) != null) {
            do {} while (index < t.length && (next = t[index++]) == null);
        }
        return e;
    }

    public final void remove() {
        Node<K,V> p = current;
        if (p == null)
            thrownew IllegalStateException();
        if (modCount != expectedModCount)
            thrownew ConcurrentModificationException();
        current = null;
        K key = p.key;
        removeNode(hash(key), key, null, false, false);
        expectedModCount = modCount;
    }
}

我們可以發現這個構造器中存在了一個do-while循環操作,目的是找到一個第一個不為空的entry。

HashIterator() {
    expectedModCount = modCount;
    Node<K,V>[] t = table;
    current = next = null;
    index = 0;
    if (t != null && size > 0) { // advance to first entry
        do {} while (index < t.length && (next = t[index++]) == null);
    }
}

而KeyIterator是extendHashIterator對象的。這里涉及到了繼承的相關概念,大家忘記的可以找相關的文章看看,或者我也可以寫一篇~~dog。

例如兩個類:

public class Father {

    public Father(){
        System.out.println("father");
    }
}
public class Son extends Father{

    public static void main(String[] args) {
        Son son = new Son();
    }
}

創建Son對象的同時,會執行Father構造器。也就會打印出father這句話。

那么這個循環操作就是我們要找的循環操作了。

總結

  1. 使用keySet遍歷,其實內部是使用了對應的iterator()方法。
  2. iterator()方法是創建了一個KeyIterator對象。
  3. KeyIterator對象extendHashIterator對象。
  4. HashIterator對象的構造方法中,會遍歷找到第一個不為空的entry。

keySet->iterator()->KeyIterator->HashIterator

責任編輯:武曉燕 來源: 碼猿技術專欄
相關推薦

2024-11-29 08:20:22

Autowired場景項目

2024-11-12 10:30:54

Docker部署數據庫

2024-06-04 00:10:00

開發拷貝

2020-12-15 10:00:31

MySQL數據庫text

2024-09-12 08:32:42

2024-07-29 08:20:10

2021-08-23 13:02:50

MySQLJOIN數據庫

2025-10-17 01:25:00

SpringIDEA@Autowired

2023-11-06 13:04:59

Python日志庫

2021-02-26 05:30:25

元素For-Each代碼

2022-01-11 10:29:32

Docker文件掛載

2025-04-29 07:06:20

2021-08-04 17:20:30

阿里巴巴AsyncJava

2021-12-08 06:53:28

HashMap面試JDK 8

2021-01-13 09:55:29

try-catch-fJava代碼

2018-11-29 14:30:42

數據庫外鍵約束應用程序

2021-07-04 14:19:03

RabbitMQ消息轉換

2020-08-31 11:20:53

MySQLuuidid

2023-09-21 10:50:23

MySQL數據庫

2024-03-11 11:02:03

Date類JavaAPI
點贊
收藏

51CTO技術棧公眾號

中国china体内裑精亚洲片| 久久久777| 欧美激情伊人电影| 国产精品996| 在线免费色视频| 大伊人狠狠躁夜夜躁av一区| 成年在线观看免费人视频| 国产精品久久久久久久久久新婚 | 成人www视频网站免费观看| 韩国女主播一区二区三区| 97在线精品视频| 国产精品久久久久aaaa樱花 | а√天堂8资源中文在线| 884aa四虎影成人精品一区| 欧美 日韩 亚洲 一区| 黑人狂躁日本妞一区二区三区| 日韩三级精品| 欧美久久久久中文字幕| 精品国产乱子伦一区二区| 大桥未久一区二区| 欧美日韩亚洲丝袜制服| 五月久久久综合一区二区小说| 亚洲精品日韩精品| 欧美日韩精品一区二区| 999成人精品视频线3| 外国精品视频在线观看| 国产欧美一区二区三区久久人妖 | 久久99精品久久久久久欧洲站 | 久久国产精品-国产精品| 亚洲.国产.中文慕字在线| 亚洲视频福利| 蜜乳av一区| 国产一区 在线播放| 97精品视频在线播放| 日韩欧美黄色动漫| 欧美激情日韩| 在线日韩成人| 欧美成熟毛茸茸| 精品国产无码在线| 一区二区激情| 两个人看的在线视频www| 99精品免费在线观看| 97色在线视频观看| 欧美日韩黄色一区二区| 美腿丝袜亚洲一区| 欧美久久精品| 日韩欧美2区| www.三区| 国产欧美欧洲| 亚洲午夜精品一区二区国产| 欧美草逼视频| 久久综合色播| 日韩理论片在线观看| 精品免费日韩av| 欧美天堂在线观看| 久久久综合视频| 国内精品伊人久久久久av影院 | 国产精品污www一区二区三区| 日韩免费在线观看| 欧美性高跟鞋xxxxhd| 99久久久无码国产精品| 美乳中文字幕| 亚洲无玛一区| 国产色婷婷国产综合在线理论片a| 亚洲激情久久久| 精品国产户外野外| youjizz国产精品| 母乳一区在线观看| 日韩欧美美女在线观看| 97久久香蕉国产线看观看| 麻豆免费在线视频| 黄色av地址| 久久精品网站视频| 成人高清dvd| 麻豆av一区| 成人av在线亚洲| 成人性生交大片免费看中文网站| 婷婷久久综合| 国产66精品| 日本国产精品| 精品国产一区二区三区久久久樱花 | 日本精品二区| 香蕉精品视频在线| 91香蕉视频导航| 最新中文字幕在线观看| 一本色道综合亚洲| 欧美性jizz18性欧美| 99久久免费精品高清特色大片| 91成人看片| 国产精品123| 欧美三级电影精品| 麻豆国产va免费精品高清在线| 成人欧美一区二区三区黑人孕妇| 免费日韩视频在线观看| 最新国产在线视频| 精品国产欧美日韩一区二区三区| 国产欧美高清在线| √天堂资源地址在线官网| 亚洲电影有码| 三级在线观看一区二区 | 国产一区视频在线看| 岛国精品视频在线播放| 亚洲视频第一页| 国产精品日韩欧美一区二区三区 | 伊人久久青草| 污网站在线观看视频| 老司机aⅴ在线精品导航| www国产精品av| 中文字幕av一区二区| 久久riav| 欧美少妇在线观看| 成人网18免费软件大全| 久久手机免费观看| 懂色av色香蕉一区二区蜜桃| 欧美男gay| 国产a区久久久| 婷婷激情成人| 国产综合婷婷| 成人av综合一区| 在线视频亚洲一区| www国产精品com| 国产精品区一区二区三在线播放 | 欧美精品一本久久男人的天堂| 成人性生交xxxxx网站| 六月婷婷激情综合| 久做在线视频免费观看| 老熟妇仑乱视频一区二区| 免费av网站在线看| 色先锋久久影院av| 国产美女视频91| 欧美一区三区四区| 97超碰人人模人人爽人人看| 国产主播中文字幕| 精品福利在线| 国产毛片精品视频| 91精品国产丝袜白色高跟鞋| 91在线观看免费高清| 欧美 日韩 国产在线观看| а√在线中文网新版地址在线| 影音先锋久久久| 天天躁日日躁狠狠躁欧美巨大小说| 精品在线视频一区| 日韩欧美中文字幕公布| 成人在线观看视频网站| 2018高清国产日本一道国产| 国产精品日韩精品在线播放| 99re在线精品| 欧美成人免费小视频| 视色,视色影院,视色影库,视色网 日韩精品福利片午夜免费观看 | 久久成人免费电影| 亚洲成人精品在线| 国产成人精品免费视频大全最热 | 国产一线二线三线在线观看| 91亚洲精品在看在线观看高清| 国产精品一区二区在线看| 精品性高朝久久久久久久| 欧美日产一区二区三区在线观看| 男女视频在线观看| 成人亚洲成人影院| 精品久久国产一区| 1区2区3区欧美| 国产精品黄视频| av亚洲在线| 国产一区中文字幕| 91精品国产91久久久久久吃药| 麻豆福利视频| 久久精品一本| 亚洲免费视频一区二区| 欧美精品成人网| 国产精品毛片久久| 亚洲成人国产精品| 无码精品a∨在线观看中文| 免费网站在线观看视频| 精品国产亚洲一区二区三区在线 | 26uuu亚洲综合色欧美 | 中文日韩电影网站| 捆绑紧缚一区二区三区在线观看| 欧美日韩国产在线一区| 一本色道久久88综合亚洲精品ⅰ| 激情综合色综合啪啪开心| 中文字幕字幕中文在线中不卡视频| 成人久久18免费网站图片| 色婷婷av在线| 亚洲欧洲成人av每日更新| 精品乱码一区二区三区| 在线视频成人| 91影院成人| 亚洲欧美国产精品专区久久| 伊人久久青青草| 国产日产精品一区| 日韩中文字幕av在线| 国产探花在线精品| 这里只有精品在线观看| 麻豆免费在线视频| 欧美日韩人人澡狠狠躁视频| 天天做天天爱天天高潮| 在线欧美日韩| 国产精品日日做人人爱| 91综合久久爱com| 伊人伊成久久人综合网站|