Java Map集合(二)

1. HashMap原理

1.1 HashMap的容量

        HashMap中使用数组作为存储元素的桶,对应的内部属性为table,如下图所示。HashMap的内部数组不是在创建HashMap对象时初始化,而是在首次存入元素时进行初始化,以减少对内存的占用。

        从源码注释中我们可以发现,官方规定table的长度总是2的幂,即2的N次方。这样设计的原因是为了保证HashMap的速度足够快。

        我们知道,不论存操作还是取操作,HashMap都使用除留取余法通过key的哈希值计算key在桶中的索引。如果能优化这一计算的速度,将会大幅优化HashMap存取操作的速度。

        在数学中有这样一条公式:X % 2^n = X & (2^n - 1) 。简单的说,当X对Y取余时,如果Y是2的幂,则可以将取余运算转换为位运算,以提高计算速度。

        综上,HashMap的容量始终是2的幂,以保证内部高效的哈希运算。

1.2 HashMap的初始容量

        与ArrayList相似,HashMap的初始容量分为默认容量和手动指定两种情况。

        当使用无参构造器创建HashMap对象时,table的初始化长度为16,由如下的静态常量指定。

        因此,默认情况下,HashMap的默认容量为16。

        HashMap支持使用带参构造器HashMap(int initialCapacity)来创建HashMap对象,并指定内部数组的初始化长度。

        此处需要注意,HashMap并不会直接使用开发者指定的长度作为内部数组的长度,而是会通过一个内部方法,计算大于开发者指定长度的最小的2的幂作为内部数组的长度。

        例如:

        因此,当开发者指定初始长度时,HashMap的容量为大于该长度的最小的2的幂。

1.3 HashMap的扩容

        HashMap中提供了桶的自动扩容机制,在满足特定的条件时自动将桶的长度扩容到原来的两倍。

        想要理解桶的扩容条件,需要先分清楚4个概念:

  • 1、容量(capacity):HashSet内部数组的长度,默认长度为16
  • 2、大小(size):HashSet中实际存储的元素的个数,默认为0
  • 3、负载因子(loadFactor):用来衡量HashSet“满”的程度,默认值为0.75f
  • 4、临界值(threshold):当size超过临界值时,HashSet将会扩容,threshold = capacity * loadFactor

        对于一个默认的HashSet来说,临界值=16 * 0.75 = 12,即当存储了超过12个元素时,HashSet会自动扩容,将容量扩大到原来的2倍,即32。

        扩容后,还会对所有的元素进行一次rehash操作,相当于对所有的元素重新做一遍Hash运算,是一项比较耗时的操作。

        由于存在上述的设计,因此开发者手动指定HashMap的初始容量时,需要计算合适的容量,而不是直接传入要存储元素的个数。具体可参考《阿里巴巴 Java开发手册》中的建议。

1.4 树化与退化

        HashMap中使用链地址法处理Hash冲突,当桶中某个位置的链表过长时,会响查询效率的情况。

        自Java 8开始,HashMap在解决哈希冲突时引入了红黑树的应用,以提高查找操作的效率。当链表长度大于等于阈值(默认为8),同时HashMap容量已达到64时,链表会转换为红黑树,从而减少查找操作的时间复杂度,这个过程称为树化(Treeify)。

        树化的2个阈值由HashMap内部的静态常量指定。

        红黑树是一种自平衡的二叉搜索树,它具有良好的平衡性能和较快的查找、插入和删除操作的时间复杂度。相比于链表,红黑树在大型哈希桶中可以提供更快的查找速度。

        同时,当红黑树中的节点数量减少到一定程度(默认为6)时,HashMap会将红黑树转换回链表。这个过程称为退化(Untreeify)。退化的阈值同样由HashMap内部的静态常量指定:

2. LinkedHashMap

2.1 LinkedHashMap概述

        HashMap虽然提供了高效的添加和查询功能,但是无法保存元素的添加顺序。在一些特定的应用场景中,可能需要保存键值对的添加顺序,此时可以使用LinkedHashMap来实现。

        例如:项目既需要提供按用户名快速查询用户信息的功能,也需要提供按用户签到顺序显示用户信息列表的功能。此时需要能够记载元素的添加顺序。

        LinkedHashMap是在HashMap的基础上维护了一个Entry的双向链表,以此记录元素之间的先后顺序。

2.2 LinkedHashMap示例

        编写代码,测试LinkedHashMap的遍历。代码示意如下:

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

public class LinkedHashMapDemo {
    public static void main(String[] args) {
        LinkedHashMap<Integer,String> map = new LinkedHashMap<>();
        // 存放元素,以键值对形式
        map.put(5, "Tom");
        map.put(3, "Jerry");
        map.put(9, "Lucy");
        // 通过entrySet方法遍历
        Set<Map.Entry<Integer,String >> entrySet = map.entrySet();
        for(Map.Entry<Integer,String> entry:entrySet){
            System.out.println("key: " + entry.getKey()+" value: " + entry.getValue());
        }
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【STM32+HAL】三轴按键PS2摇杆

一、准备工作&#xff1a; 有关CUBEMX的初始化配置&#xff0c;参见我的另一篇blog&#xff1a;【STM32HAL】CUBEMX初始化配置 有关定时器触发ADC模式配置&#xff0c;详见【STM32HAL】ADC采集波形实现 二、所用工具&#xff1a; 1、芯片&#xff1a; STM32F407VET6 2、CUBE…

小蓝本--因式分解(习题1)讲解

这几天要备战期中&#xff0c;下一期可能要等暑假了...... 小升初的压力真是紧扣于头啊&#xff0c;为了分到一个好班&#xff0c;拼了&#xff01; 对了&#xff0c;下一期可能在寒假更&#xff0c;见谅&#xff01; 1分解因式&#xff1a; 公因式&#xff1a; 答案&#xff…

发动机台架测试起动电源为发动机台架测试提供方便操作

发动机台架测试启动电源通常是指为发动机试验设备提供电力的装置&#xff0c;它可能包括交流电源、直流电源或专用的启动发电机。在进行发动机性能测试时&#xff0c;需要稳定的电力供应来驱动各种测试设备&#xff0c;如振动台、数据采集系统等。具体到电源类型常见的有市电、…

QT:label标签/进度条的使用

文章目录 设置不同格式的文本显示图片文本对齐/自动换行/缩进/边距LCDNumber倒计时 ProgressBar进度条 设置不同格式的文本 在文本格式中&#xff0c;存在富文本&#xff0c;makedown格式的文本&#xff0c;还有纯文本&#xff0c;下面就依据这三个进行举例 #include "w…

# 从浅入深 学习 SpringCloud 微服务架构(七)Hystrix(1)

从浅入深 学习 SpringCloud 微服务架构&#xff08;七&#xff09;Hystrix&#xff08;1&#xff09; 一、Hystrix&#xff1a;基于 RestTemplate 的熔断配置 1、Hystrix 介绍&#xff1a; 1&#xff09;Hystrix 是由 Netflix 开源的一个延迟和容错库&#xff0c; 用于隔离访…

nginx--配置文件

组成 主配置文件&#xff1a;nginx.conf 子配置文件&#xff1a;include conf.d/*.conf 协议相关的配置文件&#xff1a;fastcgi uwsgi scgi等 mime.types&#xff1a;⽀持的mime类型&#xff0c;MIME(Multipurpose Internet Mail Extensions)多用途互联⽹网邮件扩展类型&…

渲染 函数

DOM树 什么是渲染函数 在多数情况下&#xff0c;Vue推荐使用模板template来创建HTML。 然而在一些应用场景中&#xff0c;需要使用JavaScript创建HTML。 这时可以用渲染函数&#xff0c;它比模板更方便。 render函数的主要神秘地方就是Vue的h函数。 h()函数 h()函数是一个用于…

学习Rust的第26天:Rust中的cp

在本文中复刻了 cp 实用程序的功能&#xff0c;我想默认使其递归&#xff0c;因为每次我想复制时都输入 -R 文件夹都会觉得有点重复&#xff0c;本文代码将与前文代码保持相似&#xff0c;我们只会更改程序的核心功能和一些变量名称以匹配用例 Pseudo Code 伪代码 function cop…

C#实战—代码实现收发文件智能化

在信息化的今天&#xff0c;收发电子文档几乎是每个朋友都要经历的事情。比如班级学委和班长需要收发作业&#xff0c;企业管理者需要收发工作文件。但是&#xff01;&#xff01;&#xff01; 每到要交结果时&#xff0c;往往会发现总会有一些人没有即使交上&#xff0c;50个…

基于Springboot的校园食堂订餐系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的校园食堂订餐系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构…

区域文本提示的实时文本到图像生成;通过一致性自注意力机制的视频生成工具保持视频的一致性;专门为雪佛兰汽车设计的客服聊天机器人

✨ 1: StreamMultiDiffusion StreamMultiDiffusion是首个基于区域文本提示的实时文本到图像生成框架&#xff0c;实现了高速且互动的图像生成。 StreamMultiDiffusion 旨在结合加速推理技术和基于区域的文本提示控制&#xff0c;以克服之前解决方案中存在的速度慢和用户交互性…

从零开始学AI绘画,万字Stable Diffusion终极教程(一)

【第1期】SD入门 2022年8月&#xff0c;一款叫Stable Diffusion的AI绘画软件开源发布&#xff0c;从此开启了AIGC在图像上的爆火发展时期 率先学会SD的人&#xff0c;已经挖掘出了越来越多AI绘画有趣的玩法 从开始的AI美女、线稿上色、真人漫改、头像壁纸 到后来的AI创意字、AI…

望仙谷听谿涛

望仙谿涛 近来不知为何&#xff0c;染上喝咖啡的恶习&#xff0c;称为“恶”&#xff0c;是因为要花钱&#xff0c;而且非得是那种口感好的。 网络流行“人生无解&#xff0c;来杯拿铁”。 大抵是因为咖啡再苦&#xff0c;也比不过生活吧&#xff0c;至少咖啡可以加糖&#xff…

机器学习批量服务模式优化指南

原文地址&#xff1a;optimizing-machine-learning-a-practitioners-guide-to-effective-batch-serving-patterns 2024 年 4 月 15 日 简介 在机器学习和数据分析中&#xff0c;模型服务模式的战略实施对于在生产环境中部署和操作人工智能模型起着至关重要的作用。其中&…

STM32——WWDG(窗口看门狗)

技术笔记&#xff01; 1.WWDG&#xff08;窗口看门狗&#xff09;简介 本质&#xff1a;能产生系统复位信号和提前唤醒中断的计数器。 特性&#xff1a; 递减的计数器&#xff1b; 当递减计数器值从 0x40减到0x3F时复位&#xff08;即T6位跳变到0&#xff09;&#xff1b; …

HTML_CSS学习:CSS盒子模型

一、CSS中常用的长度单位 相关代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>CSS中常用的长度单位</title><style>html{font-size: 40px;}#d1{/*第一种长度单位&…

springboot+vue中小学文具商城购物系统网站

技术栈 前端&#xff1a;vue.jsElementUI 开发工具&#xff1a;IDEA 或者eclipse都支持 编程语言: java 框架&#xff1a; ssm/springboot 数据库: mysql 版本不限 数据库工具&#xff1a;Navicat/SQLyog都可以 详细技术&#xff1a;javaspringbootvueMYSQLMAVEN文具网站为用户…

【基于MAX98357的Minimax(百度)长文本语音合成TTS 接入教程】

【基于MAX98357的Minimax&#xff08;百度&#xff09;长文本语音合成TTS 接入教程】 1. 前言2. 先决条件2.1 硬件准备2.2 软件准备2.3 接线 3. 核心代码3.1 驱动实现3.2 代码解析 4. 播放文本5. 结论 视频地址&#xff1a; SeeedXIAO ESP32S3 Sense【基于MAX98357的Minimax&am…

8.MyBatis 操作数据库(进阶)

文章目录 1.动态SQL插入1.1使用注解方式插入数据1.2使用xml方式插入数据1.3何时用注解何时用xml&#xff1f;1.4使用SQL查询中有多个and时&#xff0c;如何自动去除多余and1.4.1方法一&#xff1a;删除and之后的代码如图所示&#xff0c;再次运行1.4.2方法二&#xff1a;加上tr…

MATLAB实现遗传算法优化同时取送货的车辆路径问题VRPSDP

同时取送货的车辆路径问题VRPSDP的数学模型如下: 模型假设 所有车辆的载重、容量等性能相同。每个客户的需求&#xff08;送货和取货量&#xff09;是已知的&#xff0c;且在服务过程中不会改变。车辆的行驶速度恒定&#xff0c;不考虑交通拥堵等实时路况变化。每个客户点只能…
最新文章