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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

为什么说 HashMap 是无序的

發布時間:2023/12/14 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 为什么说 HashMap 是无序的 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 為什么說 HashMap 是無序的

HashMap 和 HashSet 遍歷元素時是無序的,這恐怕是一個常識了,但是你有沒有想過為什么是無序的?TreeMap 和 LinkedHashMap 是有序的,那又為什么是有序的呢?

本節我們從源碼分析的角度來理一理這件事情.

首先說 HashMap 是如何遍歷的,一般來說有兩種遍歷方式,我們用常用的這一種,使用 entrySet 的 iterator 方法,如下

Map<String, Object> map = new HashMap<>(); Iterator<Map.Entry<String, Object>> iterator = map.entrySet().iterator(); while (iterator.hasNext()) {Map.Entry<String, Object> next = iterator.next();System.out.println(next.getKey() + "\t" + next.getValue()); } //源碼來源于JDK1.8 public Set<Map.Entry<K,V>> entrySet() {Set<Map.Entry<K,V>> es;//我們看到這里new了一個EntrySetreturn (es = entrySet) == null ? (entrySet = new EntrySet()) : es; } public final Iterator<Map.Entry<K,V>> iterator() {//然后我們看EntrySet的源碼中的iterator返回了EntryIteratorreturn new EntryIterator(); }//這里是EntryIterator的定義,其中的next方法便是遍歷元素的順序 final class EntryIterator extends HashIteratorimplements Iterator<Map.Entry<K,V>> {//nextNode方法執行HashIterator中的nextNode(),public final Map.Entry<K,V> next() { return nextNode(); } }abstract class HashIterator {Node<K,V> next; // next entry to returnNode<K,V> current; // current entryint expectedModCount; // for fast-failint index; // current slotHashIterator() {expectedModCount = modCount;Node<K,V>[] t = table;current = next = null;index = 0;if (t != null && size > 0) { // advance to first entrydo {} while (index < t.length && (next = t[index++]) == null);}}final Node<K,V> nextNode() {Node<K,V>[] t;Node<K,V> e = next;if (modCount != expectedModCount)throw new ConcurrentModificationException();if (e == null)throw new NoSuchElementException();//下面這個代碼的意思就是如果數組當前位置為空就去尋找下一個位置,參考下圖if ((next = (current = e).next) == null && (t = table) != null) { '核心答案'do {} while (index < t.length && (next = t[index++]) == null);}return e;}//部分源碼省略 }

HashMap 中元素的遍歷是按照從數組起始位置開始,首先將當前 bucket 下的所有元素遍歷完成,然后到下一個 bucket,bucket 與 bucket 之間如果為空就跳到下一個 bucket, 直到將所有的元素遍歷出來。顯而易見,元素插入的位置并不是這樣的順序,因此才說 HashMap 是無序的.

參考這張圖片:

2. TreeMap 和 LinkedHashMap 是如何實現有序的

TreeMap 的底層數據結構是一棵紅黑樹,紅黑樹上的元素都是有順序的.
LinkedHashMap 底層數據結構就是一個雙向鏈表,元素遍歷的順序就是鏈表從前到后的順序,因此也是有序的.

3. 多次遍歷HashMap ,順序不變

插入順序和遍歷順序不一致,但是多次遍歷HashMap ,順序不變

import java.util.*;public class Test {public static void main(String[] args) throws InterruptedException {HashMap map = new HashMap();map.put("ss","ss");map.put("aaaa","aaaa");map.put("ccc","ccc");map.put("bbbbb","bbbbb");for(int i =0;i<100;i++){print(map);}}public static void print(HashMap<String, String> list) {Iterator it = list.entrySet().iterator();while (it.hasNext()) {System.out.print(" " + it.next());}System.out.println();}}

結果:

ss=ss bbbbb=bbbbb ccc=ccc aaaa=aaaass=ss bbbbb=bbbbb ccc=ccc aaaa=aaaass=ss bbbbb=bbbbb ccc=ccc aaaa=aaaass=ss bbbbb=bbbbb ccc=ccc aaaa=aaaass=ss bbbbb=bbbbb ccc=ccc aaaa=aaaa...

參考

為什么說 HashMap 是無序的

總結

以上是生活随笔為你收集整理的为什么说 HashMap 是无序的的全部內容,希望文章能夠幫你解決所遇到的問題。

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