HashMap使用foreach循环为什么有时是有序的?

HashMap本质上存储数据是无序的,但是某些情况下使用foreach循环时输出似乎有序,这实际上是由于哈希表的实现细节和哈希冲突的处理方式导致的巧合现象。

hashMap无序性的本质:

1.hashMap的实现是基于哈希表+链表/红黑树实现

1.哈希表决定健的位置(桶的位置)

2.链表/红黑树处理哈希冲突

3.迭代顺序是由哈希表的桶遍历顺序和链表遍历顺序共同决定。

2.为什么foreach有时看起来有序:

1.小数据集且hash冲突少

当数据集较小时,健的哈希值可能正好分布在连续的桶中:

HashMap<Integer,String>map=new HashMap<>();
map.put(1,"A");
map.put(2,"B");
map.put(3,"C");
//输出可能巧合地显示顺序为:1=A, 2=B, 3=C
map.forEach((key,value)->System.out.println(key+"="+value));

2.哈希计算的特殊性:

如果健的哈希值经过扰动后恰好按照插入顺序排列,遍历时会呈现有序的假象。

例如使用Integer作为健时,哈希值直接等于数值。

map.put(10, "X");  // 哈希值=10,落入桶10
map.put(20, "Y");  // 哈希值=20,落入桶20
map.put(30, "Z");  // 哈希值=30,落入桶30

3.扩容未发生:

当哈希表未发生扩容时,现有健的存储位置不会改变,若后续插入的健哈希值递增,遍历桶时会顺序输出。

3.有序替代方案:

特性HashMapLinkedHashMapTreeMap
顺序保证插入顺序/访问顺序自然排序/自定义排序
时间复杂度O(1)O(1)O(log n)
内部结构哈希表哈希表+双向链表红黑树
使用场景快速查找需要保留插入顺序的场景需要排序的场景

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值