HashMap的底层原理

一:HashMap的节点:HashMap是一个集合,键值对的集合,源码中每个节点用Node<K,V>表示

static class Node<K,V> implements Map.Entry<K,V> {

final int hash;

final K key;

V value;

Node<K,V> next;

Node是一个内部类,这里的key为键,value为值,next指向下一个元素,可以看出HashMap中的元素不是一个单纯的键值对,还包含下一个元素的引用。

二:HashMap的数据结构:HashMap的数据结构为 数组+(链表或红黑树),上图:

为什么采用这种结构来存储元素呢?

数组的特点:查询效率高,插入,删除效率低。

链表的特点:查询效率低,插入删除效率高。

在HashMap底层使用数组加(链表或红黑树)的结构完美的解决了数组和链表的问题,使得查询和插入,删除的效率都很高。

三:HashMap存储元素的过程:

有这样一段代码:

HashMap<String,String> map = new HashMap<String,String>();

map.put("刘德华","张惠妹");

map.put("张学友","大S");

现在我要把键值对 “刘德华”,”张惠妹”存入map:

第一步:计算出键“刘德华”的hashcode,该值用来定位要将这个元素存放到数组中的什么位置.

什么是hashcode?

在Object类中有一个方法:

public native int hashCode();

该方法用native修饰,所以是一个本地方法,所谓本地方法就是非java代码,这个代码通常用c或c++写成,在java中可以去调用它。

调用这个方法会生成一个int型的整数,我们叫它哈希码,哈希码和调用它的对象地址和内容有关.

哈希码的特点是:

对于同一个对象如果没有被修改(使用equals比较返回true)那么无论何时它的hashcode值都是相同的

对于两个对象如果他们的equals返回false,那么他们的hashcode值也有可能相等

明白了hashcode我们再来看元素如何通过hashcode定位到要存储在数组的哪里,通过hashcode值和数组长度取模我们可以得到元素存储的下标。

刘德华的hashcode为20977295 数组长度为 16则要存储在数组索引为 20977295%16=1的地方

 

可以分两种情况:

1. 数组索引为1的地方是空的,这种情况很简单,直接将元素放进去就好了。

2. 已经有元素占据了索引为1的位置,这种情况下我们需要判断一下该位置的元素和当前元素是否相等,使用equals来比较。

如果使用默认的规则是比较两个对象的地址。也就是两者需要是同一个对象才相等,当然我们也可以重写equals方法来实现我们自己的比较规则最常见的是通过比较属性值来判断是否相等。

如果两者相等则直接覆盖,如果不等则在原元素下面使用链表的结构存储该元素

每个元素节点都有一个next属性指向下一个节点,这里由数组结构变成了数组+链表结构,红黑树又是怎么回事呢?

因为链表中元素太多的时候会影响查找效率,所以当链表的元素个数达到8的时候使用链表存储就转变成了使用红黑树存储,原因就是红黑树是平衡二叉树,在查找性能方面比链表要高.

四:HashMap中的两个重要的参数:HashMap中有两个重要的参数:初始容量大小和加载因子,初始容量大小是创建时给数组分配的容量大小,默认值为16,用数组容量大小乘以加载因子得到一个值,一旦数组中存储的元素个数超过该值就会调用rehash方法将数组容量增加到原来的两倍,专业术语叫做扩容.

在做扩容的时候会生成一个新的数组,原来的所有数据需要重新计算哈希码值重新分配到新的数组,所以扩容的操作非常消耗性能.

创建HashMap时我们可以通过合理的设置初始容量大小来达到尽量少的扩容的目的。加载因子也可以设置,但是除非特殊情况不建议设置.

【无人机】基于改进粒子群算法的无人机路径规划研究[和遗传算法、粒子群算法进行比较](Matlab代码实现)内容概要:本文围绕基于改进粒子群算法的无人机路径规划展开研究,重点探讨了在复杂环境中利用改进粒子群算法(PSO)实现无人机三维路径规划的方法,并将其与遗传算法(GA)、标准粒子群算法等传统优化算法进行对比分析。研究内容涵盖路径规划的多目标优化、避障策略、航路点约束以及算法收敛性和寻优能力的评估,所有实验均通过Matlab代码实现,提供了完整的仿真验证流程。文章还提到了多种智能优化算法在无人机路径规划中的应用比较,突出了改进PSO在收敛速度和全局寻优方面的优势。; 适合人群:具备一定Matlab编程基础和优化算法知识的研究生、科研人员及从事无人机路径规划、智能优化算法研究的相关技术人员。; 使用场景及目标:①用于无人机在复杂地形或动态环境下的三维路径规划仿真研究;②比较不同智能优化算法(如PSO、GA、蚁群算法、RRT等)在路径规划中的性能差异;③为多目标优化问题提供算法选型和改进思路。; 阅读建议:建议读者结合文中提供的Matlab代码进行实践操作,重点关注算法的参数设置、适应度函数设计及路径约束处理方式,同时可参考文中提到的多种算法对比思路,拓展到其他智能优化算法的研究与改进中。
### HashMap 底层数据结构 HashMap底层结构采用 **数组 + 链表/红黑树** 的方式实现。这种结构结合了数组的快速访问特性和链表/红黑树在冲突处理中的高效性。HashMap 通过哈希函数将键(key)转换为哈希值,然后根据哈希值计算出键值对在数组中的存储位置(索引)[^2]。 - **数组**:用于存储数据的主结构,数组的每个元素被称为“桶”(bucket)。 - **链表**:当多个键值对被映射到同一个桶时,使用链表来存储这些冲突的键值对。 - **红黑树**:当某个桶中的链表长度超过一定阈值(默认为8),链表会转换为红黑树以提升查找效率[^2]。 ### HashMap 的实现原理 HashMap 的核心实现原理围绕 **哈希算法** 和 **冲突解决机制** 展开: 1. **哈希算法**:HashMap 使用键的 `hashCode()` 方法结合扰动函数生成最终的哈希值。通过 `(n - 1) & hash` 计算出键值对的存储位置,其中 `n` 是数组的长度。这种方式确保哈希值均匀分布,减少碰撞概率[^5]。 2. **冲突解决**:当两个不同的键经过哈希计算后映射到相同的桶时,会发生哈希冲突。HashMap 使用 **拉链法** 解决冲突,即在每个桶中维护一个链表,存储所有冲突的键值对。当链表长度超过阈值时,链表会转换为红黑树以提升性能。 3. **动态扩容**:当 HashMap 中的元素数量接近其容量与负载因子(默认为0.75)的乘积时,HashMap 会自动扩容(通常是当前容量的两倍),并重新分配所有键值对到新的桶中。这个过程称为 **再哈希**(rehash)[^5]。 4. **线程安全性**:HashMap 不是线程安全的,在多线程环境下可能会导致数据不一致或死循环等问题。如果需要线程安全的实现,可以使用 `ConcurrentHashMap`[^3]。 ### 示例代码:HashMap 的基本使用 ```java import java.util.HashMap; public class HashMapExample { public static void main(String[] args) { // 创建一个 HashMap 实例 HashMap<String, Integer> map = new HashMap<>(); // 添加键值对 map.put("Apple", 10); map.put("Banana", 20); map.put("Orange", 30); // 获取值 System.out.println("Apple: " + map.get("Apple")); // 输出 Apple: 10 // 遍历 HashMap for (String key : map.keySet()) { System.out.println(key + ": " + map.get(key)); } // 删除键值对 map.remove("Banana"); // 检查是否包含某个键 if (map.containsKey("Orange")) { System.out.println("Contains Orange"); } } } ``` ### 性能优化与使用场景 HashMap 的性能优势主要体现在 **快速的插入、查找和删除操作**,其平均时间复杂度为 O(1)。这种高效性得益于哈希算法的均匀分布和冲突处理机制的优化(链表转红黑树)。 在实际开发中,HashMap 被广泛用于缓存、索引、快速查找等场景。例如,在金融领域中,HashMap 和 `ConcurrentHashMap` 被频繁用于处理高并发的数据存储和访问需求[^3]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值