创建网站做搞笑视频,php 网站开发 pdf,桥梁建设期刊的投稿网站,零基础可以用阿里云做网站吗文章目录 Java中的HashMap什么是HashMap#xff1f;对比其他Map中put()方法HashMap中put()方法使用示例 HashMap中put()源码解析手绘流程图实现原理源码探究#xff08;JDK 1.8#xff09; 设计put()的意义总结 Java中的HashMap
什么是HashMap#xff1f;
HashMap是Java中… 文章目录 Java中的HashMap什么是HashMap对比其他Map中put()方法HashMap中put()方法使用示例 HashMap中put()源码解析手绘流程图实现原理源码探究JDK 1.8 设计put()的意义总结 Java中的HashMap
什么是HashMap
HashMap是Java中常用的数据结构之一它基于哈希表实现提供了快速的键值对存取能力。在HashMap中put方法是最常用的方法之一用于将键值对存储到HashMap中。本文将深入探究HashMap的put方法的实现原理解析其内部数据结构和算法并探讨设计put方法的意义。
对比其他Map中put()方法
可以看一下博主的博客了解HashMap、TreeMap和LinkedHashMap三者的使用Java-数据结构二-MapHashMap、TreeMap、LinkedHashMap HashMap、TreeMap和LinkedHashMap都是Java中常用的Map实现类它们在put方法的实现上有一些区别。 HashMap的put方法 HashMap使用哈希表来存储键值对通过键的哈希码和哈希函数来确定键值对在哈希表中的存储位置。当发生哈希冲突时HashMap使用链表或红黑树来解决冲突。HashMap的put方法具有O(1)的平均时间复杂度。 TreeMap的put方法 TreeMap使用红黑树来存储键值对根据键的自然顺序或自定义比较器来进行排序。在插入键值对时TreeMap会根据键的顺序将键值对插入到相应的位置以保持有序性。TreeMap的put方法具有O(log n)的时间复杂度。 LinkedHashMap的put方法 LinkedHashMap继承自HashMap底层仍然使用哈希表来存储键值对。LinkedHashMap在HashMap的基础上使用双向链表来维护键值对的插入顺序或访问顺序。在插入键值对时LinkedHashMap会将键值对插入到链表的尾部以保持插入顺序或访问顺序。LinkedHashMap的put方法具有O(1)的平均时间复杂度。
HashMap的put方法使用哈希表来存储键值对适用于需要高效存储和查找键值对的场景。TreeMap的put方法使用红黑树来存储键值对适用于需要有序存储和查找键值对的场景。LinkedHashMap的put方法在HashMap的基础上使用双向链表来维护插入顺序或访问顺序适用于需要保持插入顺序或访问顺序的场景。
HashMap中put()方法使用示例
以下是一个简单的Java代码示例展示了如何使用HashMap的put方法
import java.util.HashMap;public class HashMapExample {public static void main(String[] args) {// 创建一个HashMap对象HashMapString, Integer hashMap new HashMap();// 使用put方法添加键值对hashMap.put(apple, 1);hashMap.put(banana, 2);hashMap.put(cherry, 3);// 使用get方法获取键对应的值int value hashMap.get(banana);System.out.println(The value of banana is: value);}
}HashMap中put()源码解析
手绘流程图 实现原理
在Java中HashMap的put方法的实现原理可以分为以下几个步骤
1.首先根据键的哈希值计算出键的哈希码。HashMap使用键的哈希码来确定键值对在哈希表中的存储位置。
2.接下来通过哈希码计算出键值对在哈希表中的索引位置。HashMap使用一个称为“哈希函数”的算法来计算索引位置。常用的哈希函数是将哈希码与哈希表的容量进行取模运算得到索引位置。
3.如果该索引位置上没有其他键值对则直接将键值对存储在该位置上。如果该索引位置上已经存在其他键值对则发生了“哈希冲突”。
4.当发生哈希冲突时HashMap使用链表或红黑树来解决冲突。在JDK1.8之前HashMap使用链表来解决冲突即在冲突的索引位置上将新的键值对插入到链表的尾部。而在JDK1.8及以后的版本中当链表长度超过一定阈值时HashMap会将链表转换为红黑树以提高查找效率。
5.最后将键值对成功存储在哈希表中并返回先前关联的值如果存在。如果该索引位置上已经存在其他键值对则需要遍历链表或红黑树找到对应的键值对并更新其值。
通过以上步骤HashMap的put方法成功将键值对存储在哈希表中。需要注意的是当哈希表的负载因子即存储的键值对数量与容量的比值超过一定阈值时HashMap会进行扩容操作以保持哈希表的性能。
源码探究JDK 1.8
public V put(K key, V value) {return putVal(hash(key), key, value, false, true);
}final V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {NodeK,V[] tab; NodeK,V p; int n, i;// table未初始化或者长度为0进行扩容if ((tab table) null || (n tab.length) 0)n (tab resize()).length;// (n - 1) hash 确定元素存放在哪个桶中桶为空新生成结点放入桶中(此时这个结点是放在数组中)if ((p tab[i (n - 1) hash]) null)tab[i] newNode(hash, key, value, null);// 桶中已经存在元素处理hash冲突else {NodeK,V e; K k;//快速判断第一个节点table[i]的key是否与插入的key一样若相同就直接使用插入的值p替换掉旧的值e。if (p.hash hash ((k p.key) key || (key ! null key.equals(k))))e p;// 判断插入的是否是红黑树节点else if (p instanceof TreeNode)// 放入树中e ((TreeNodeK,V)p).putTreeVal(this, tab, hash, key, value);// 不是红黑树节点则说明为链表结点else {// 在链表最末插入结点for (int binCount 0; ; binCount) {// 到达链表的尾部if ((e p.next) null) {// 在尾部插入新结点p.next newNode(hash, key, value, null);// 结点数量达到阈值(默认为 8 )执行 treeifyBin 方法// 这个方法会根据 HashMap 数组来决定是否转换为红黑树。// 只有当数组长度大于或者等于 64 的情况下才会执行转换红黑树操作以减少搜索时间。否则就是只是对数组扩容。if (binCount TREEIFY_THRESHOLD - 1) // -1 for 1sttreeifyBin(tab, hash);// 跳出循环break;}// 判断链表中结点的key值与插入的元素的key值是否相等if (e.hash hash ((k e.key) key || (key ! null key.equals(k))))// 相等跳出循环break;// 用于遍历桶中的链表与前面的e p.next组合可以遍历链表p e;}}// 表示在桶中找到key值、hash值与插入元素相等的结点if (e ! null) {// 记录e的valueV oldValue e.value;// onlyIfAbsent为false或者旧值为nullif (!onlyIfAbsent || oldValue null)//用新值替换旧值e.value value;// 访问后回调afterNodeAccess(e);// 返回旧值return oldValue;}}// 结构性修改modCount;// 实际大小大于阈值则扩容if (size threshold)resize();// 插入后回调afterNodeInsertion(evict);return null;
}
设计put()的意义
设计put方法的意义在于提供了一种简单而高效的方式来存储和查找键值对。HashMap的put方法具有O(1)的平均时间复杂度即使在发生哈希冲突的情况下通过链表或红黑树的处理也能保持较快的查找性能。这使得HashMap成为了处理大量数据的理想选择尤其在需要频繁进行键值对操作的场景下。
总结
本文深入探究了Java中HashMap的put方法的实现原理。通过了解其内部数据结构和算法我们可以更好地理解和使用HashMap在实际开发中更加高效地进行键值对的存储和查找操作。同时我们也探讨了设计put方法的意义以及提供了相关的Java代码示例。希望本文对读者有所帮助让大家对HashMap的put方法有更深入的理解。