面试题:为什么HashMap 使用的时候指定容量?

文章目录

  • 前言
  • 正文
    • 为什么要指定容量?


前言

其实可以看到我写了这么久的博客,很少去写hashMap的东西。
为什么?因为这个东西感觉是java面试必备的,我感觉大家都看到腻了,所以一直没怎么去写hashMap相关的。

本篇内容:

  • 举例说明 HashMap 使用的时候指定容量 错误用法;
  • 源码走读,HashMap初始容量的 计算方式;
  • 源码走读扩容的点;
  • 正确应该怎么去用,一定要理解再用;
  • 一些杂谈。

提示:以下是本篇文章正文内容,下面案例可供参考

正文

不开玩笑,真的都知道指定容量,但是有些用对了,有些没用对。

在这里插入图片描述

为什么要指定容量?

这个原由,都不用说,阿里的java开发手册就说的很明白:

在这里插入图片描述

其实核心点,就是避免数据量慢慢增加,导致反复触发扩容,影响性能。

于是乎就很多错误的使用方式了(虽热影响不大):

错误理解使用示例 ① :
分页查询出来的数据,需要转换成 Map, 因为分页是固定了一页最多15条。

所以出现了这个代码:

Map<String, String> map = new HashMap<>(15);

或者是

Map<String, String> map = new HashMap<>(userPageList.size());

错误理解使用示例 ② :
类型type 有 4种, 要放到一个map里面,返回去。

所以出现了这个代码:

Map<Integer, String> map = new HashMap<>(4);

错误理解使用示例 ③:
一个参数map,里面想放2个参数。

所以出现了这个代码:

Map<String, String> map = new HashMap<>(2);

不多举例,其实这几个错误示例,都是错在指定容量的 值上。

正例:initialCapacity = (需要存储的元素个数/负载因子)+ 1

默认 指定是 传入 16, 16* 0.75=12 , 所以扩容阈值是12 。

说到这里,大家应该知道为什么上面是错误用法了吧?

比如我们想 存 4个元素到Map, 我们为了避免后面触发扩容影响性能(其实元素少性能没多少影响), 就指定了 4 :

Map<Integer, String> map = new HashMap<>(4);

其实这样 4x0.75= 3 ,那么如果存放第四个元素的时候,就会触发扩容

在这里插入图片描述

这样就是违背了我们开始指定 的 4 的最初用意。

实战看看这个错误使用场景的情况:

同过反射,将capacity属性的权限拿到,可以直接打印出来看下capacity的变化,就知道是否触发了扩容:

public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {Map<String, String> map = new HashMap<>(4);Class<?> mapType = map.getClass();Method capacity = mapType.getDeclaredMethod("capacity");capacity.setAccessible(true);map.put("1", "第一个元素插入");System.out.println("capacity : " + capacity.invoke(map) + "    size : " + map.size());map.put("2", "第二个元素插入");System.out.println("capacity : " + capacity.invoke(map) + "    size : " + map.size());map.put("3", "第三个元素插入");System.out.println("capacity : " + capacity.invoke(map) + "    size : " + map.size());map.put("4", "第四个元素插入");System.out.println("capacity : " + capacity.invoke(map) + "    size : " + map.size());}

看下打印效果:

在这里插入图片描述

为什么,当size =3 ,也就是插入三个元素的时候还没变。

因为我们初始化容量值传入的 4, 4* 0.75 =3. 扩容阈值是 3!

在这里插入图片描述
当插入第四个元素的时候, 就超过了扩容阈值,所以触发了扩容,所以看的最后其实是进行了一次扩容,打印出来的capacity是 8.

那么我们应该传多少?

正例:initialCapacity = (需要存储的元素个数/负载因子)+ 1

4/0.75 + 1 = 6.3333333

我们指定传6么?还是传 7 ?

指定6:

在这里插入图片描述
指定7:
在这里插入图片描述
指定6,7 都没区别好像, 值得庆祝的是,没有再次触发扩容。

那么为啥没区别呢?

在这里插入图片描述
HashMap会转换成大于该capacity 的第一个2的幂作为容量 。
所以传5,6,7,8 都是 8 ;

传9,10,11,12,13,14,15,16 都是 16 ;

好了不多啰嗦了, 最后再补一嘴, 默认指定容量,其实就是 内存换性能。

所以真正去使用指定容量的时候, 需要考虑:如果我是一个定时任务,允许跑1小时。。。我需要考虑性能么?

或者如果我服务内存很小,我是不是要对内存省吃俭用?

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

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

相关文章

JAVA删除excel指定列

首先POI没有提供删除列的API&#xff0c;所以就需要用其他的方式实现。 在 java - Apache POI xls column Remove - Stack Overflow 这里找到了实现方式&#xff1a; 先将该列所有值都清空&#xff0c;然后将该列之后的所有列往前移动。 下面的工具类中 deleteColumns(Inpu…

如何使用navicat图形化工具远程连接MariaDB数据库【cpolar内网穿透】

公网远程连接MariaDB数据库【cpolar内网穿透】 文章目录 公网远程连接MariaDB数据库【cpolar内网穿透】1. 配置MariaDB数据库1.1 安装MariaDB数据库1.2 测试局域网内远程连接 2. 内网穿透2.1 创建隧道映射2.2 测试随机地址公网远程访问3. 配置固定TCP端口地址3.1 保留一个固定的…

c# sqlite 修改字段类型

因为sqlite不支持直接修改字段类型&#xff0c; 所以只能创建新的表&#xff0c;再将原始数据复制过去。具体操作步骤如下&#xff1a; 第一步&#xff0c; 将表“tableName”的名称修改为 “oldTable” string queryString string.Format("ALTER TABLE {0} RENAME TO …

Kafka笔记

一、Kafka 概述 1.1.定义 传统定义&#xff1a;Kafka 是一个分布式的基于发布/订阅模式的消息队列&#xff0c;主要用于大数据实时处理领域。最新定义&#xff1a;Kafka 是一个开源的分布式事件流平台&#xff0c;被数千家公司用于高性能数据管道、流分析、数据集成和关键任务…

167. 两数之和 II - 输入有序数组、Leetcode的Python实现

博客主页&#xff1a;&#x1f3c6;看看是李XX还是李歘歘 &#x1f3c6; &#x1f33a;每天分享一些包括但不限于计算机基础、算法等相关的知识点&#x1f33a; &#x1f497;点关注不迷路&#xff0c;总有一些&#x1f4d6;知识点&#x1f4d6;是你想要的&#x1f497; ⛽️今…

修改 jquery dialog title

官网&#xff1a; $("#xxx").dialog("option", "title", "xxx").dialog(open);

深入理解Docker之:存储卷相关概念详解和分析

深入理解Docker之&#xff1a;存储卷相关概念详解和分析 1. 为什么要使用存储卷 Docker镜像由多个只读层叠加而成&#xff0c;启动容器时&#xff0c;Docker会加载只读镜像层&#xff0c;并在镜像栈顶部添加一个读写层如果运行中的容器修改了现有的一个已经存在的文件&#x…

行政快递管理高效化教程

能不能做好因公寄件管理&#xff0c;影响着企业内部运转的效率。我们知道&#xff0c;基本上每家企业的因公寄件&#xff0c;是由行政部门来统筹管理的...... 企业员工只知道&#xff0c;在公司寄快递&#xff0c;找行政。殊不知行政快递管理&#xff0c;不仅仅是“寄件”这么…

Docker添加软链接,解决c盘占用问题

Docker的文件&#xff0c;默认放在 c 盘&#xff0c;用多了很影响系统的速度。 解决方法&#xff1a; 为 Docker 路径添加软链接。 在 windows 搜索框&#xff0c;输入cmd &#xff0c;以管理员身份运行 cmd * 执行命令&#xff1a; “C:\Program Files\Docker” 这个地址是…

【2023.10.27练习】C语言-字符串转换

计算机能力挑战初赛2020.17题 题目描述&#xff1a; 有一组均由字符A~Z和a~z组成的字符串,其中要求将字符串中各字符按如下要求进行转换&#xff1a; A<->z、B<->y、C<->x、...... 、X<->c、Y<->b、Z<->a 输入&#xff1a; 第一行输入…

如何使用Abaqus进行摩擦生热仿真

Abaqus除了可以对结构进行强度分析&#xff0c;同样也有强大的固体传热分析功能&#xff0c;下面通过一个简单的实例演示Abaqus的双向热固耦合分析。 因为本案例涉及物体表面辐射&#xff0c;因此需要定义绝对零度和输入史蒂夫-波兹曼常数&#xff0c;如下&#xff1a; 本次分…

Python手搓C4.5决策树+Azure Adult数据集分析

前言 课上的实验 由于不想被抄袭&#xff0c;所以暂时不放完整代码 Adult数据集可以在Azure官网上找到 Azure 开放数据集中的数据集 - Azure Open Datasets | Microsoft Learn 数据集预处理 删除难以处理的权重属性fnlwgt与意义重复属性educationNum去除重复行与空行删除…

控制输入流,从控制台打印到文件中,更改输出的位置

public static void main(String[] args) throws IOException {PrintStream printStream System.out;//在默认情况下&#xff0c;PrintStream 输出数据的位置 标准输出&#xff0c;即显示器printStream.print("Tom,hello");/*public void print(String s) {if (s n…

R语言代码示例

以下是一个使用R语言和httrOAuth库的下载器程序&#xff0c;用于下载的内容。程序使用以下代码。 # 安装和加载必要的库 install.packages("httr") install.packages("httrOAuth") library(httr) library(httrOAuth) ​ # 设置 http_proxy <- "du…

Prevalence and prevention of large language model use in crowd work

本文是LLM系列文章&#xff0c;针对《Prevalence and prevention of large language model use in crowd work》的翻译。 众包工作中使用大型语言模型的流行率和预防 摘要1 研究1&#xff1a;LLM使用的普遍率2 研究2&#xff1a;LLM使用的预防3 讨论4 材料与方法 摘要 我们表…

LeetCode 2698. 求一个整数的惩罚数:模拟(二进制枚举)

【LetMeFly】2698.求一个整数的惩罚数&#xff1a;模拟&#xff08;二进制枚举&#xff09; 力扣题目链接&#xff1a;https://leetcode.cn/problems/find-the-punishment-number-of-an-integer/ 给你一个正整数 n &#xff0c;请你返回 n 的 惩罚数 。 n 的 惩罚数 定义为所…

卷积神经网络的感受野

经典目标检测和最新目标跟踪都用到了RPN(region proposal network)&#xff0c;锚框(anchor)是RPN的基础&#xff0c;感受野(receptive field, RF)是anchor的基础。本文介绍感受野及其计算方法&#xff0c;和有效感受野概念。 1.感受野概念 在典型CNN结构中&#xff0c;FC层(…

DAY36 738.单调递增的数字 + 968.监控二叉树

738.单调递增的数字 题目要求&#xff1a;给定一个非负整数 N&#xff0c;找出小于或等于 N 的最大的整数&#xff0c;同时这个整数需要满足其各个位数上的数字是单调递增。 &#xff08;当且仅当每个相邻位数上的数字 x 和 y 满足 x < y 时&#xff0c;我们称这个整数是单…

PyCharm社区版安装

PyCharm社区版安装 到中国官网下载 https://www.jetbrains.com/zh-cn/pycharm/download/?sectionwindows 首次创建项目&#xff0c;会自动下载安装Python 3.9 社区版的区别 社区版的区别

数组的最长递减子序列

求一个数组的最长递减子序列 如{9&#xff0c;4&#xff0c;3&#xff0c;2&#xff0c;5&#xff0c;4&#xff0c;3&#xff0c;2}的最长递减子序列为{9&#xff0c;5&#xff0c;4&#xff0c;3&#xff0c;2} 思路&#xff1a;动态规划 构建与原数组同等容量的辅助数组dp,记…