HashMap的put方法(Java7)和putVal方法(Java8)

目录

    • 数组+链表:存在性能最坏情况O(n)
      • Java7的HashMap的put方法思路
    • 数组+链表+红黑树:性能提高到O(logn)
      • Java8的HashMap的putVal方法思路

数组+链表:存在性能最坏情况O(n)

Java8以前,HashMap底层数据结构采用数组+链表的结构。
数组特点:查询快,增删慢。
链表特点:查询慢,增删较快。
HashMap:结合了数组和链表的优势。同时HashMap的操作是非Synchronized,因此效率比较高。

Java7的HashMap的put方法思路

put源码:

public V put(K key, V value) {if (table == EMPTY_TABLE) {inflateTable(threshold);}if (key == null)return putForNullKey(value);int hash = hash(key);int i = indexFor(hash, table.length);for (Entry<K,V> e = table[i]; e != null; e = e.next) {Object k;if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {V oldValue = e.value;e.value = value;e.recordAccess(this);return oldValue;}}modCount++;addEntry(hash, key, value, i);return null;}

addEntry源码:

/*** Adds a new entry with the specified key, value and hash code to* the specified bucket.  It is the responsibility of this* method to resize the table if appropriate.** Subclass overrides this to alter the behavior of put method.*/void addEntry(int hash, K key, V value, int bucketIndex) {if ((size >= threshold) && (null != table[bucketIndex])) {resize(2 * table.length);hash = (null != key) ? hash(key) : 0;bucketIndex = indexFor(hash, table.length);}createEntry(hash, key, value, bucketIndex);}

方法简述:
1、初始化HashMap,若Entry数组类型的table为空,inflated(膨胀,扩容意思)一个table,threshold默认=初始容量=16;
2、对key求Hash值,然后再计算table下标;
3、如果没有碰撞,即数组中没有相应的键值对,直接放入桶(bucket)中,如果碰撞了,以链表的方式链接到后面;
4、如果键值对已经存在就替换旧值;
5、如果桶满了(容量16*加载因子0.75),就需要扩容resize();

但是,存在坏情况:如果通过哈希散列运算得到的是同一个值,即总是分配到同一个桶中,使某个桶的链表长度很长。
由于链表查询需要从头开始遍历,最坏情况下,HashMap性能变为O(n)。

数组+链表+红黑树:性能提高到O(logn)

Java8以后,HashMap底层数据结构采用数组+链表+红黑树的结构。
通过常量TREEIFY_THRESHOLD=8和UNTREEIFY_THRESHOLD=6来控制链表与红黑树的转化。

Java8的HashMap的putVal方法思路

putVal源码:

final V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {Node<K,V>[] tab; Node<K,V> p; int n, i;if ((tab = table) == null || (n = tab.length) == 0)n = (tab = resize()).length;if ((p = tab[i = (n - 1) & hash]) == null)tab[i] = newNode(hash, key, value, null);else {Node<K,V> e; K k;if (p.hash == hash &&((k = p.key) == key || (key != null && key.equals(k))))e = p;else if (p instanceof TreeNode)e = ((TreeNode<K,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);if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1sttreeifyBin(tab, hash);break;}if (e.hash == hash &&((k = e.key) == key || (key != null && key.equals(k))))break;p = e;}}if (e != null) { // existing mapping for keyV oldValue = e.value;if (!onlyIfAbsent || oldValue == null)e.value = value;afterNodeAccess(e);return oldValue;}}++modCount;if (++size > threshold)resize();afterNodeInsertion(evict);return null;}

在Java7源码基础上增加了链表和红黑树的转化。
如果链表长度超过阈值8,就把链表转换成红黑树,如果链表长度低于6,就把红黑树转回链表。改变了最坏情况下O(n),性能提高到O(logn)。
注意:Java7中数组里的元素叫Entry,Java8及以后改名为Node(节点)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/549191.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

管道过滤器(Pipe-And-Filter)模式

按照《POSA(面向模式的软件架构)》里的说法&#xff0c;管道过滤器&#xff08;Pipe-And-Filter&#xff09;应该属于架构模式&#xff0c;因为它通常决定了一个系统的基本架构。管道过滤器和生产流水线类似&#xff0c;在生产流水线上&#xff0c;原材料在流水线上经一道一道的…

Java创建对象的方式——反序列化创建对象

目录Java创建对象的几种方式反序列化创建对象思路代码示例Java创建对象的几种方式 Java创建对象的方式共有4种。分别为&#xff1a; 1、通过new语句实例化一个对象。 2、通过反射机制创建对象。 3、通过clone()方法创建一个对象。 4、通过反序列化的方式创建对象。 思考&#…

redis知识归纳

目录Redis有哪些数据结构&#xff1f;有大量key需要设置同一时间过期&#xff0c;需要注意什么&#xff1f;Redis分布式锁怎么回事&#xff1f;假设Redis里有1亿个key&#xff0c;其中有10万个key是以同一个固定前缀开头&#xff0c;如何将它们全部找出&#xff1f;如何用Redis…

PCI_Express规范第七章解读-Software Initialization and configuration

7.Software Initialization and configuration PCI EXPRESS Configuration model 支持两种配置空间的访问机制&#xff1a; -PCI 兼容配置机制&#xff1a;100%的二进制兼容PCI 2.3中定义的&#xff0c;以及兼容早期的OS或类似的总线枚举和配置软件。 -PCI Express增强配置机制…

List「Object[]」转Map「Integer,String」处理

题目 有一个List<Object[]>&#xff0c;里面的元素分别是[1,“a”]&#xff0c;[2,“b”]&#xff0c;[1,“c”]&#xff0c;[2,“d”]…&#xff0c;请写一个函数将其转换为一个Map<Integer,String>&#xff0c;以List的Object[]第一个元素为关键字&#xff0c;将…

Asp.net基础概念之 事件

.NET Framework中的事件 事件体系结构 引发事件的对象叫做事件源。事件源发布它可以引发的事件。事件的类型总是委托类型&#xff0c;这个委托类型的签名定义了处理该事件的方法的签名。定义事件处理程序方法的对象称为事件接收方。事件接收方预订要在事件源上处理的事件事件接…

synchronized同步方法概述

synchronized同步方法 1、“线程安全”与“非线程安全”&#xff1a; 非线程安全情况&#xff1a;多个线程对同一个对象中的实例变量进行并发访问时&#xff0c;产生脏读。 解决方法&#xff1a;对实例变量的值进行同步处理。 2、方法内的变量为线程安全 3、实例变量非线程安…

as3:sprite作为容器使用时,最好不要指定width,height

官方解释&#xff1a; 除 TextField 和 Video 对象以外&#xff0c;没有内容的显示对象&#xff08;如一个空的 Sprite&#xff09;的高度为 0&#xff0c;即使您尝试将 height 设置为其它值&#xff0c;也是这样。 如果您设置了 height 属性&#xff0c;则 scaleY 属性会相应调…

1002 写出这个数 (20分)-Java

题目 读入一个正整数 n&#xff0c;计算其各位数字之和&#xff0c;用汉语拼音写出和的每一位数字。 输入格式&#xff1a; 每个测试输入包含 1 个测试用例&#xff0c;即给出自然数 n 的值。这里保证 n 小于 10 ​100。 输出格式&#xff1a; 在一行内输出 n 的各位数字之和…

成为LINUX系统管理员几点规则

要成为一名合格的LINUX管理员&#xff0c;一般来说都要懂得如下几点规则&#xff1a; 规则1&#xff1a;了解LINUX的一切。首先&#xff0c;在了解以下规则之前&#xff0c;笔者必须向大家说明的是&#xff0c;即使最基本的LINUX系统管理员都是要经过不断的学习和长时间实践才能…

Facebook图片存储架构技术全解析

Haystack提出了一种通用的基于HTTP的对象存储&#xff0c;它含有指针&#xff0c;映射到存储对象。在Haystack中以指针储存照片&#xff0c;把数以十万计的图像聚集到一个Haystack存储文件&#xff0c;从而消除了元数据负荷。这就使得元数据的开销非常小&#xff0c;并且使我们…

Shiro授权流程图

Shiro授权流程Shiro授权流程图Shiro授权流程图 根据Shiro授权流程&#xff0c;绘制流程图如下&#xff1a;

assert

[编辑本段]概述  Assert - 断言 编写代码时&#xff0c;我们总是会做出一些假设&#xff0c;断言就是用于在代码中捕捉这些假设&#xff0c;可以将断言看作是异常处理的一种高级形式。断言表示为一些布尔表达式&#xff0c;程序员相信在程序中的某个特定点该表达式值为真。可…

Shiro并发登录人数控制遇到的问题和解决

shiro并发登录人数控制遇到的问题和解决问题1:KickoutSessionControlFilter不起作用问题2:KickoutSessionControlFilter中cache为null空指针异常问题3:服务器重启后首页访问&#xff1a;subject.getPrincipal()报ClassCastException异常系统环境参考资料问题1:KickoutSessionCo…

新的网站上线 linux视野

开通了新的网站www.linuxsight.com会一直专注着Linux文章的写作转载于:https://blog.51cto.com/87243/354662

js中toFixed方法的两个坑

js中toFixed方法的两个坑toFixed返回结果是string&#xff0c;后续使用它计算会错误toFixed返回结果可能出现负零-0.00toFixed返回结果是string&#xff0c;后续使用它计算会错误 代码演示&#xff1a; 类型判断代码示例&#xff1a; var stringNum (100.101).toFixed(2); v…

Redhat linux 5.3 基于bond的heartbeat

一、设置bond 1.修改网卡cd /etc/sysconfig/network-scripts/cp ifcfg-eth0 ifcfg-bond0vi ifcfg-bond0DEVICEbond0 ONBOOTyes BOOTPROTOnone IPADDR192.168.1.200 NETMASK255.255.255.0 GATEWAY192.168.1.1 USERCTLno TYPEEthernetvi ifcfg-eth0DEVICEeth0 ONBOOTyes BOOTPROT…

外挂:一个很杯具的关键字

在网页挂马泛滥的时代&#xff0c;盗号***不缺少传播到用户电脑的通道&#xff0c;因为只需要找一些与游戏有关的网站&#xff0c;或者在流量大的网站把网马一挂&#xff0c;就不愁钓不着鱼。如今&#xff0c;时代在变迁&#xff0c;安全软件已经成功的解决了网页挂马这个难题&…

java.lang.ClassNotFoundException: retrofit2.Retrofit$Builder解决思路

ClassNotFoundException报错具体问题报错详情推测可能是jar包问题问题总结自定义依赖缺少依赖jar具体问题 Caused by: java.lang.NoClassDefFoundError: retrofit2/converter/simplexml/SimpleXmlConverterFactory报错详情 org.springframework.web.util.NestedServletExcept…

varnish排错

●Troubleshooting varnish&#xff08;varnish排错&#xff09;<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />有时候varnish会出错&#xff0c;为了使您知道该检查哪里&#xff0c;您可以检查varnishlog&#xff0c;/var/log…