Java HashMap 的数据结构和底层原理以及其在Jdk8,Jdk11,Jdk17的一些变化,以及一些常问的面试

news2024/10/21 12:50:06

往期回顾

[Java基础] 基本数据类型

[Java基础] 运算符

[Java基础] 流程控制

[Java基础] 面向对象编程

[Java基础] 集合框架

[Java基础] 输入输出流

[Java基础] 异常处理机制

[Java基础] Lambda 表达式

目录

Java HashMap 的数据结构和底层原理

JDK 8, JDK 11, JDK 17 中的变化

常见面试题及答案

Java HashMap 的数据结构和底层原理

数据结构:

  • HashMap 内部维护了一个数组,称为桶(bucket)或槽(slot),每个桶可以存储一个或多个键值对。
  • 每个桶默认是链表形式,当桶内的元素数量超过一定阈值时(通常是8),链表会被转换为红黑树以提高查找效率。

哈希函数:

  • 当向 HashMap 中插入键值对时,首先会调用键的 hashCode() 方法来获取哈希码。
  • 然后通过哈希码与当前容量减一进行按位与操作来确定键值对应该存放在哪个桶中。

解决哈希冲突:

  • 如果两个不同的键具有相同的哈希码,那么它们就会被放置在同一个桶内。
  • 在 JDK 8 之前版本中,使用单向链表处理哈希冲突。
  • 在 JDK 8 及之后版本中,如果桶中的节点数超过 TREEIFY_THRESHOLD (默认为8),则链表会被转换成红黑树。

扩容机制:

  • HashMap 中的元素数量超过当前容量乘以负载因子(默认为0.75)时,就会触发扩容。
  • 扩容通常是将现有容量翻倍,并重新分配所有的元素到新的桶数组中。

JDK 8, JDK 11, JDK 17 中的变化

  • JDK 8:
    - 引入了红黑树优化。当某个桶中的节点数达到TREEIFY_THRESHOLD时,该桶从链表转换为红黑树。
    - 增加了懒加载特性,即初始化时不创建桶数组,而是在第一次插入元素时才创建。
  • JDK 11:
    - 主要是性能上的微调和一些内部实现细节的优化。
    - 对于安全性和稳定性的改进也间接影响了 HashMap 的表现。
  • JDK 17:
    - 没有对 HashMap 进行重大功能更新,但持续进行了性能和内存管理方面的优化。
    - 包括垃圾收集器(如ZGC)的改进,这可能间接提高了 HashMap 的性能。

常见面试题及答案

  1. 什么是哈希碰撞?如何解决?
    - :哈希碰撞是指不同的键产生了相同的哈希码,导致它们映射到了 HashMap 的同一个桶上。Java HashMap 通过链表(或红黑树)来解决这个问题,将发生碰撞的键值对链接起来。
  2. 为什么 HashMap 不保证顺序?
    - :因为 HashMap 是基于哈希表实现的,其内部的数据存储位置依赖于键的哈希码。随着添加、删除等操作,可能会导致哈希码重新计算,从而改变元素的位置。因此,HashMap 不保证任何特定的顺序。
  3. HashMap** 和 Hashtable 有什么区别?**
    - HashMap 是非线程安全的,允许 null 键和 null 值;而 Hashtable 是线程安全的,不允许 null 键和 null 值。此外,HashMap 提供了更多的方法来控制容量增长策略。
  4. HashMap** 的初始容量是多少?负载因子的作用是什么?**
    - HashMap 的默认初始容量是 16,默认负载因子是 0.75。负载因子用于决定何时需要扩容。当元素数量达到容量乘以负载因子时,HashMap 会自动扩容。
  5. 为什么 HashMap 使用红黑树而不是 AVL 树?
    - :红黑树提供了更好的最坏情况下的性能保障,而且对于插入和删除操作来说,红黑树的旋转次数更少,因此在频繁变更的情况下更为合适。此外,红黑树在实际应用中通常比 AVL 树有更好的平衡性,更适合于动态数据集。
  6. HashMap中put是如何实现的?
       - :首先计算key的hashCode值,其次根据hashCode值确定元素在数组中的位置,接着如果位置为空,则直接添加元素,最后如果位置已有元素,则判断key是否相同(地址相同或equals方法返回true),若相同则替换旧值;若不同,则采用链表或红黑树处理碰撞。
  7. 为什么HashMap的默认初始化长度为16,并且每次扩容都是2倍?
       - :第一,为了数据的均匀分布和减少哈希碰撞,HashMap的默认初始化长度选择为2的幂(如16)。第二,每次扩容为2倍可以确保新数组的长度仍然是2的幂,从而方便使用位运算来确定元素在数组中的位置。

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

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

相关文章

nginx解决非人类使用http打开的443,解决网安漏扫时误扫443端口带来的问题

一、问题描述 正常访问https的站点时,使用网址https://www.baidu.com,但会有一种错误的访问请求http://www.baidu.com:443,一般都是非人类所为,如漏洞扫描工具,那么请求以后带来的后果是个错误页面 400 Bad Request T…

Vue及项目结构介绍

今天滴学习目标!!! 项目结构介绍1.Vue 项目文件结构2. 文件结构详解2.1 index.html2.2 src/main.js2.3 src/App.vue2.4 src/components/2.5 src/assets/2.6 package.json 3. 项目启动 首先我们先学习Vue项目结构,我们创建Vue项目时…

【专题】计算机网络之物理层

计算机网络体系结构: 1. 物理层的基本概念 物理层考虑的是怎样才能在连接各种计算机的传输媒体上传输数据比特流,而不是指具体的传输媒体。 作用:尽可能屏蔽掉不同传输媒体和通信手段的差异。 用于物理层的协议也常称为物理层规程 (procedu…

js.矩阵置零

链接:73. 矩阵置零 - 力扣(LeetCode) 题目: 给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1: 输入:matrix [[1,1,1],…

如何使用Java语言调用API数据

在当今的数据驱动世界中,API(应用程序编程接口)成为了连接不同服务和数据源的桥梁。无论是社交媒体数据、金融市场信息还是地理位置服务,API都能提供一种便捷的方式来获取这些数据。Java,作为最受欢迎的编程语言之一&a…

无mac电脑在苹果开发者上传构建版本

我们登录苹果开发者网站的后台,进入app store后,发现上架的页面需要上传一个构建版本。 这个构建版本的意思就是我们的应用二进制文件,是上架最重要的文件。但是在苹果开发者后台是无法直接上传这个文件的,它提示我们可以使用xco…

VSCODE c++不能自动补全的问题

最近安装了vscode,配置了C/C扩展,也按照网上说的配置了头文件路径 我发现有部分头文件是没办法解析的,只要包含这些头文件中的一个或者多个,就没有代码高亮和代码自动补全了,确定路径配置是没问题的,因为鼠…

Caffeine Cache解析(一):接口设计与TinyLFU

Caffeine is a high performance Java caching library providing a near optimal hit rate. 自动加载value, 支持异步加载基于size的eviction:frequency and recency基于时间的过期策略:last access or last write异步更新valuekey支持weak referenceva…

RK3588部署及其RKNPU工具链使用学习

文章目录 RKNPU 推理框架推理软件框架RKNPU 硬件层:RKNPU 驱动层:RKNPU 应用层 RKNN 模型RKNN 的工具链介绍RKNN 软件栈整体介绍RKNN-Toolkit2 功能介绍RKNPU2-SDK总结 开发环境搭建PC 端采用 虚拟机上的 Ubunt20.04 系统安装 anconda通过 conda 创建虚拟…

机器学习“捷径”:自动特征工程全面解析

引言 在机器学习项目中,特征工程是影响模型性能的关键步骤。它通过从原始数据中提取出更有用的特征,帮助模型更好地捕捉数据中的模式。然而,传统的特征工程过程往往需要大量的领域知识和实验调整,是一项耗时费力的工作。 近年来…

关于modbus与HMI车载侧屏通信的错误机制处理

目录 1.关于6个人机交互功能按钮逻辑图设计 2.错误处理机制 1.关于6个人机交互功能按钮逻辑图设计 初次的设计想法是按钮亮表示大家能按,但要是想在按一次,发送有效数据,就得先按亮,在按灭。这里以上料区为例,其它区…

Midjourney中文版:创意无界,绘梦成真

在数字艺术的浩瀚宇宙中,Midjourney中文版如同一颗璀璨的新星,以其独特的魅力和无限可能,引领着每一位创作者探索创意的无限边界。作为专为国内用户打造的AI绘画工具,Midjourney中文版不仅继承了原版的核心优势,更在本…

基于cloudreve(Docker应用)搭建网盘服务,用于目录的分享和在线预览。

文章目录 I 基于cloudreve(Docker应用)搭建网盘服务安装主要功能设置角色最大容量II 知识扩展:网盘类的文件预览需求背景: iOS可以直接预览PDF等常见格式文件,但是Android浏览器需要先下载文件,才能查看文件内容,因此需要搭建支持目录的分享和在线预览的MinIO文件服务提供…

【Redis】Zset类型常用命令

文章目录 一. Zset有序集合简介.二. 添加元素相关命令.2.1 向有序集合中添加元素(zadd) 三. 查询元素相关操作.3.1 查询有序集合中的元素个数( zcard zcount)3.2 查询指定区间内的元素(zrange zrevrange zrangebyscore)3.3 查询有序集合中指定成员的排名(zrank zrevrank )3.4 查…

AI大模型学习路线路径,巨详细!

大模型技术已经成为推动人工智能发展的关键力量。无论你是初学者还是有经验的开发者,想要掌握大模型应用,都需要遵循一定的学习路线。 从核心技术解析到模型微调与私有化部署,逐步深入大模型应用的世界。 这份学习路线图详细的介绍了那年每…

规划控制复现:Apollo LQR横向控制(算法原理推导与流程)

本文在前文已经搭建好的规划控制验证平台中进行LQR算法的复现: 1.车辆动力学建模 汽车轨迹跟踪误差模型示意图如下: 为车辆横向速度,为车辆纵向速度;和 分别为质心到前、 后轴的距离 ; 为车辆的横 摆角 ; 和 分别为车辆前 、 后轮的侧偏角。并设车辆…

【C++】哈希表的模拟实现

目录 一、闭散列(开放定址定法) 1、哈希表的结构: 2、哈希表的插入: 3、哈希表的查找: 4、哈希表的删除: 二、开散列(哈希桶) 1、哈希表的结构: 2、构造与析构&a…

若依前后分离版集成积木报表进行token传递

若依分离板集成积木报表就不说了需要的请移步:若依前后分离版集成积木报表-CSDN博客 考虑到前端摸鱼不干活,所以一般都是前后端都干,我这里前后端都搞上,你们直接抄,抄完接着去摸鱼,代码不美观,轻喷 一、…

【JavaEE】【多线程】synchronized和死锁

目录 一、synchronized详解1.1 互斥1.2 可重入 二、死锁2.1 死锁成因2.2 避免死锁 一、synchronized详解 1.1 互斥 synchronized 会起到互斥效果, 某个线程执行到某个对象的 synchronized 中时, 其他线程如果也执行到 同一个对象 synchronized 就会阻塞等待. 语法&#xff1…

AI时代程序员何去何从?提升自我还是被淘汰出局!

AI 在编程界的使用变得越来越普遍了。随着 ChatGPT 的横空出世,各种大语言模型如雨后春笋不断出现。国外如谷歌 Bard、Anthropic 的 Claude,国内如百度文心一言、阿里通义千问、讯飞星火认知大模型、昆仑万维天工大模型等。 想想看,以前得花好…