面试必备:HashMap底层源码原来是这么简单(分析)

news2024/11/15 9:57:17

微信公众号:SteveCode
关注可了解更多的编程及开发经验。问题或建议,请公众号留言;
专注Java技术干货分享,Java技术、数据结构、相关工具、Spring全家桶、intellij idea……
如果你觉得对你有帮助,欢迎赞赏

在这里插入图片描述
transient 发现了这个关键字:(不懂啥意思)赶快去查一下

transient 只能修饰变量哈!被他修饰的变量不能序列化。

什么是序列化和序列化

序列化:对象转字节, 反序列化:字节转对象

什么时候会用到实例化

想将对象做网络传输或者写入数据库、文件夹流中

transient帮助文档

为什么要用modCount

也就相当于版本控制。当你在增删改的时候都会 ++modCount。

public final void forEach(Consumer<? super K> action) {
            Node<K,V>[] tab;
            if (action == null)
                throw new NullPointerException();
            if (size > 0 && (tab = table) != null) {
            // 刚开始把modCount 复制给mc 
                int mc = modCount; 
                for (int i = 0; i < tab.length; ++i) {
                    for (Node<K,V> e = tab[i]; e != null; e = e.next)
                        action.accept(e.key);
                }
               // 循环完了之后在看一下 modCount 有没有发生改变 。如果发生就说明 这个集合内部数据有改变。就报:ConcurrentModificationException
                if (modCount != mc)
                    throw new ConcurrentModificationException();
            }
        }

容量与扩容机制

hashMap 默认容量为 DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
最大容量:MAXIMUM_CAPACITY = 1 << 30;
负载因子默认:DEFAULT_LOAD_FACTOR = 0.75f

注意扩容机制容量和hashmap默认容量不能搞混 了哈!

之前我一直任务hashMap 的默认容量为 DEFAULT_INITIAL_CAPACITY*DEFAULT_LOAD_FACTOR=12【错误的】
扩容机制:集合的size大小达到size=12的时候才会发生扩容。

在这里插入图片描述

JDK8的HashMap为什么要引入红黑树

当HashMap的key冲突过多时,会导致链表过长。而链表的查询效率很差,因此引入红黑树优化查询效率。

为什么当链表长度大于8-1 并且 table >64 时候才会转红黑树而不是一开始直接使用红黑树:

树节点占用空间是普通节点的两倍,因此在开始较短时候使用链表,占用空间少,查询性能也相差不大。但是当链表越来越长,查询效率逐渐变低,为保证查询效率才会舍弃链表转为红黑树,以空间换时间。

根据统计,HashMap链表长度为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) {
         // tab p 当前方法初始化一个
        Node<K,V>[] tab; Node<K,V> p; int n, i;
        // tab = table这个还没初始化 ==null   这个数组没有实例化  tab.length=0
        if ((tab = table) == null || (n = tab.length) == 0)
        // 初始化数据或者扩容的方法 resize()
            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);
                        // 什么时候转红黑树:链表长度 >= 8 - 1 &&数组长度.length > 64
                        if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                            treeifyBin(tab, hash);
                        break;
                    }
                    if (e.hash == hash &&
                        ((k = e.key) == key || (key != null && key.equals(k))))
                        break;
                    p = e;
                }
            }
            // key相同的时候走
            if (e != null) { // existing mapping for key
                V oldValue = e.value;
                if (!onlyIfAbsent || oldValue == null)
                    e.value = value;
                afterNodeAccess(e);
                return oldValue;
            }
        }
        ++modCount;
        if (++size > threshold)
            resize();
        afterNodeInsertion(evict);
        return null;
    }

面试必备:HashMap底层源码原来是这么简单(分析)视频教程

功能描述:

  • map.put()代码底层3
  • resize 扩容源码底层4
  • 什么时候发起扩容如何扩容3 threshold 默认参数 下 size > threshold=12
  • 什么时候转红黑树5 链表长度大于7 binCount >= 8 - 1 &&tab.length > 64
  • 初始化数据的时机3 resize()
  • transient 什么意思 1
  • modCount 用这个有什么用2
  • 为什么转红黑树6
  • 什么是序列化和反序列化

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

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

相关文章

re:Invent现场访谈:云计算如何重塑智能制造

众所周知&#xff0c;近年来包括中国和美国在内&#xff0c;世界上各个主要国家对制造业的关注度都在不断提升。也正因为如此&#xff0c;在2022亚马逊云科技re:Invent全球大会上&#xff0c;有关云计算技术在智能制造行业的应用&#xff0c;也理所当然地成为了诸多与会嘉宾关注…

【JMeter】线程组jp@gc - Stepping Thread Group(逐步线程组)

jpgc - Stepping Thread Group 逐步线程组 Action to be taken after a Sample error 发生sample错误时 Continue 继续 Start Next Thread Loop 开始新的线程 Stop Thread 停止线程 Stop Test 停止测试 Stop Test Now 立即停止测试 Threads Scheduling Parameters 线程调度…

STM32+雷龙SD NAND(贴片SD卡)完成FATFS文件系统移植与测试

一、前言 在STM32项目开发中&#xff0c;经常会用到存储芯片存储数据。 比如&#xff1a;关机时保存机器运行过程中的状态数据&#xff0c;上电再从存储芯片里读取数据恢复&#xff1b;在存储芯片里也会存放很多资源文件。比如&#xff0c;开机音乐&#xff0c;界面上的菜单图…

使用SpringBoot快速构建Web API

Dubbo 框架现在在国内的中小企业当中已经成为 Java 生态下服务化的事实标准&#xff0c;出现这种状态的原因很多&#xff0c;比如 Dubbo 框架设计优秀、文档和资料丰富、配置灵活、特性丰富等&#xff0c;但最主要的&#xff0c;我认为是 Java 开发人员对速度这一因素的痴迷。 …

详解设计模式:解释器模式

解释器模式&#xff08;interpreter pattern&#xff09;&#xff0c;是在 GoF 23 种设计模式中定义了的行为型模式。 解释器模式 这种模式被用在 SQL 解析、符号处理引擎等。 解释器模式 给定一个语言&#xff0c;定义它的文法的一种表示&#xff0c;并定义一个解释器&#xf…

HTTP状态码是什么?

文章目录HTTP状态码1. 消息&#xff1a;1xx2. 成功&#xff1a;2xx3. 重定向&#xff1a;3xx4. 请求错误&#xff1a;4xx5. 服务器错误&#xff1a;5xxHTTP状态码 HTTP 状态码&#xff08;HTTP Status Code&#xff09;是一个表示服务器响应状态的 3 位整数代码。比如当服务器…

[Database] 关系型数据库中的MVCC是什么?怎么理解?原理是什么?MySQL是如何实现的?

文章目录前言并发控制并发控制的实现与锁的本质MVCC是什么&#xff1f;MVCC的多版本&#xff08;Multi-Version&#xff09;指的是什么&#xff1f;MVCC的实现方式&#xff1f;MySQL的实现PostgreSQL的实现结语前言 在并发场景下&#xff0c;如果我们不对数据做保护&#xff0c…

分布式文件存储系统FastDFS[1]-介绍以及安装

一、分布式文件存储 1.分布式文件存储的由来 在我们的项目中有很多需要存储的内容出现&#xff0c;比如图片&#xff0c;视频&#xff0c;文件等等&#xff0c;在早期的时候用户量不大&#xff0c;产生的文件也不是很多&#xff0c;这时我们可以把文件和服务程序放在一个服务器…

STAAD.Pro CONNECT Edition

STAAD.Pro CONNECT Edition Bentley STAAD或STAAD Pro软件是分析和设计世界第三世界的第一款最佳工程软件&#xff0c;对于金属、混凝土、木材、铝和冷金属的专业选择&#xff0c;设计几乎所有类型的塑料、石化、隧道、桥梁、蜡烛等结构专业的功能和软件中任何数据大小的使用。…

Java课程案例学习(3)

2.1 学生管理系统实现步骤 案例需求 针对目前我们的所学内容&#xff0c;完成一个综合案例&#xff1a;学生管理系统&#xff01;该系统主要功能如下&#xff1a; 添加学生&#xff1a;通过键盘录入学生信息&#xff0c;添加到集合中 删除学生&#xff1a;通过键盘录入要删…

Jcmd 虚拟机诊断利器

Jcmd 虚拟机诊断利器 Java虚拟机&#xff08;JVM&#xff09;是运行Java程序的抽象化的计算器。今天&#xff0c;来学习下如何轻松诊断正在运行的JVM。 JDK本身中提供了许多可用的工具&#xff0c;可以用于各种开发、监视和故障排除活动。推荐使用jcmd&#xff0c;简单易懂&a…

[附源码]计算机毕业设计南通大学福利发放管理系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

ThinkPHP6综合业务管理系统

有需要请私信或看评论链接哦 可远程调试 ThinkPHP6综合业务管理系统一 介绍 综合业务管理系统基于ThinkPHP6开发&#xff0c;数据库mysql&#xff0c;前端Layui&#xff0c;后台模板ok-admin。管理员登录系统后可对场所&#xff0c;分类&#xff0c;用户&#xff0c;运营商&am…

图片扫描仪第一弹,我实现了一个办公位简笔画

来一波对比 其实我工位还有点手办&#xff0c;一个植物&#xff0c;实在不会画&#xff0c;于是画了个基础版的。 办公位简笔画 虽然&#xff0c;这个工位上没有一个动画&#xff0c;但是图形和实物神似&#xff0c;所以可以用另一个动总结这个简笔画&#xff0c;那就是生动…

量子计算(十一):常见逻辑门以及含义

文章目录 常见逻辑门以及含义 一、Hadamard&#xff08;H&#xff09;门 二、Pauli-X 门 三、Pauli-Y 门 四、Pauli-Z 门 五、旋转门&#xff08;rotation operators&#xff09; 1、RX&#xff08;θ&#xff09;门 2、RY&#xff08;θ&#xff09;门 3、RZ&#xf…

深入理解计算机系统

hi&#xff0c;大家好&#xff0c;我是大师兄&#xff0c;让我们一起复习了一遍计算机系统核心知识&#xff0c;希望大家早日掌握这些核心知识&#xff0c;打造自己坚实的基础&#xff0c;为自己目标慢慢积累&#xff0c;等到自己春天的到来。详细点击查看-> 极客星球。计算…

PDF解除密码怎么操作?教你一键解除密码

我们在处理工作文件时&#xff0c;经常会有一些文件是加密状态的&#xff0c;这种文件必须要输入密码才可以打开&#xff0c;这时候就造成了很多不便&#xff0c;如果文件需要打印&#xff0c;我们就必须先输入密码&#xff0c;而且在每次查看文件前&#xff0c;都必须输入密码…

记录一次 在linux 搭建的mysql迁移到docker容器中

上篇文章写道&#xff0c;我腾讯云被攻击了&#xff0c;然后我各种删除木马文件&#xff0c;但在这个过程中&#xff0c;有些系统文件没认到&#xff0c;以为是木马文件&#xff0c;就删除了&#xff0c;各种处理无果&#xff0c;打开腾讯云的救援模式&#xff0c;备份了些重要…

【数据库】mysql索引

DB索引&#xff1a; 如果表创建了索引&#xff0c;那么DB会维护一张关于索引和主键关系的表 好处&#xff1a;快速查找数据 缺点&#xff1a;要额外维护一张表&#xff0c;会额外占用空间&#xff0c;对于表数据的更新操作都涉及更新索引 索引的操作 创建索引&#xff1a;…

LeetCode 74. 搜索二维矩阵

&#x1f308;&#x1f308;&#x1f604;&#x1f604; 欢迎来到茶色岛独家岛屿&#xff0c;本期将为大家揭晓LeetCode 74. 搜索二维矩阵&#xff0c;做好准备了么&#xff0c;那么开始吧。 &#x1f332;&#x1f332;&#x1f434;&#x1f434; 一、题目名称 LeetCode 74.…