哈希——Java 中的 HashMap 的工作原理是什么?

考察点:JAVA 哈希表
参考回答: HashMap 类有一个叫做 Entry 的内部类。这个 Entry 类包含了 key-value 作为实例变量。每 当往 hashmap 里面存放 key-value 对的时候,都会为它们实例化一个 Entry 对象,这个 Entry 对象就会存储在前面提到的 Entry 数组 table 中。Entry 具体存在 table 的那个位置是 根据 key 的 hashcode()方法计算出来的 hash 值(来决定)。

理解:
hashmap 是无序的但是实际输出有序。
HashMap的无序是指不会记录插入的顺序,也不会根据特定规则进行排序;
但是HashMap存值的时候会根据key的hashCode()来计算存储的位置(位置是散列的,所以说其无序);
你使用的key是String类型,String重写的hashCode()计算出的位置,遍历的时候恰好是"001",“003”,“005"的顺序;
PS:可以打印一下"001”,“003”,"005"的hashCode()再对16求个余数,然后再往里面加一个"011"和"012"再打印一下。

题目来自:牛客网
理解参考:百度知道

### Java HashMap 实现原理 #### 数据结构 `HashMap` 是基于 **哈希表** 的 `Map` 接口实现,用于存储键值对 (key-value pairs)[^3]。它的底层数据结构由数组和链表组成,在某些情况下还会涉及红黑树。 在 JDK 1.8 及以后版本中,`HashMap` 使用的是 **数组 + 链表 + 红黑树** 的组合形式[^2]。具体来说: - 数组是核心容器,每个位置称为桶 (bucket),通过计算 key 的 hash 值定位到对应的 bucket。 - 当多个键映射到同一个 bucket 时,会发生冲突。此时,`HashMap` 使用链表来解决冲突问题。 - 如果某个链表长度超过一定阈值(默认为 8),为了提高查询效率,该链表会被转换成红黑树[^4]。 #### 初始化与扩容机制 `HashMap` 默认初始容量为 16,并且总是使用 2 的幂次方作为容量大小。当实际存储的元素数量达到负载因子乘以当前容量时 (`size >= threshold`),触发扩容操作。扩容过程中,新容量变为原容量的两倍,并重新分配所有的键值对到新的 buckets 中。 #### 存储单元 Node 类型 `HashMap` 定义了一个名为 `Node<K,V>` 的静态内部类表示单个存储单元——即节点[^1]。它实现了 `Map.Entry<K,V>` 接口,具有四个字段:`hash`, `key`, `value`, 和指向下一个节点的引用 `next`。 以下是简化版的 `Node` 结构: ```java static class Node<K,V> implements Map.Entry<K,V> { final int hash; final K key; V value; Node<K,V> next; Node(int hash, K key, V value, Node<K,V> next) { this.hash = hash; this.key = key; this.value = value; this.next = next; } public final K getKey() { return key; } public final V getValue() { return value; } } ``` #### put 方法流程分析 调用 `put(K key, V value)` 插入或更新键值对的过程如下: 1. 计算给定 key 的 hash 值; 2. 利用此 hash 值找到对应 bucket 的索引位置; 3. 若目标 bucket 尚未被占用,则直接创建一个新的 `Node` 并放置其中; 4. 否则遍历已存在的链表/红黑树查找是否有相同 key 的节点;若有,则替换旧值;若无,则新增一个节点至链表尾部或者插入红黑树; 5. 检查是否需要调整为红黑树形态以及判断是否超出 load factor 导致需执行 resize 扩容动作。 #### 多线程安全性讨论 需要注意的是,标准 `HashMap` 不具备线程安全性特性。如果尝试在一个多线程环境中共享未经同步保护的实例可能会引发诸如死循环等问题(JDK 1.7 版本下的情况), 或者出现数据覆盖现象(适用于 JDK 1.8+) 。因此对于并发访问需求较高的场合建议考虑其他替代品如 `ConcurrentHashMap`. --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值