Java中HashMap如何存储Character键?为何keySet输出无序?
HashMap的keySet()输出顺序与插入顺序不符的原因
public static void main(String[] args) { Map<Character, Integer> map = new HashMap(); map.put('A',1); map.put('a',1); map.put('f',5); map.put('t',5); map.put('m',4); map.put('r',3); System.out.println(map.keySet()); }
这是因为HashMap本身不保证键的遍历顺序与插入顺序一致,它的底层基于哈希表实现,键的存储位置由以下逻辑决定:
- Character类型的
hashCode()返回其对应的Unicode编码值,比如'A'对应65、'a'对应97、'r'对应114等。 - HashMap会对键的哈希值做扰动处理(
(h = key.hashCode()) ^ (h >>> 16)),再通过与数组长度-1做按位与运算(默认数组长度为16,即& 15)计算出存储的数组下标。
以你代码中的字符为例,经过计算后各键对应的数组下标为:
- 'A' → 65 & 15 = 1
- 'a' → 97 & 15 = 1
- 'r' → 114 & 15 = 2
- 't' → 116 & 15 = 4
- 'f' → 102 & 15 = 6
- 'm' → 109 & 15 = 13
keySet()的遍历逻辑是按数组下标从小到大的顺序,依次遍历每个桶中的元素;同一个桶中的元素按插入顺序排列(元素较少时为链表结构),所以最终输出顺序就是[A, a, r, t, f, m],和插入顺序无关。
如果需要保留插入顺序,可以使用LinkedHashMap替代HashMap,它继承自HashMap,通过维护双向链表记录元素插入顺序,调用keySet()会按插入顺序返回键集合。
内容的提问来源于stack exchange,提问作者Ashwin Nair
相关产品推荐
相关产品推荐

