为什么说 HashMap 是无序的
生活随笔
收集整理的這篇文章主要介紹了
为什么说 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 是无序的的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Riak介绍
- 下一篇: 高性能RPC框架gRPC竟恐怖如斯~