面试题:为什么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,一经查实,立即删除!

相关文章

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

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

Kafka笔记

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

修改 jquery dialog title

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

行政快递管理高效化教程

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

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

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

如何使用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…

卷积神经网络的感受野

经典目标检测和最新目标跟踪都用到了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,记…

代码随想录算法训练营第3天| 203.移除链表元素 、 707.设计链表 、 206.反转链表

JAVA代码编写 203. 移除链表元素 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,6,3,4,5,6], val 6 输出&#xff1a;[1,2,3,4,5]示…

Steger算法实现结构光光条中心提取(python版本)

Steger算法原理 对结构光进行光条中心提取时,Steger算法是以Hessian矩阵为基础的。它的基础步骤如下所示: 从Hessian矩阵中求出线激光条纹的法线方向在光条纹法线方向上将其灰度分布按照泰勒多项式展开,求取的极大值即为光条在该法线方向上的亚像素坐标。对于二维离散图像来…

【黑马程序员】mysql基础篇笔记

2023年10月26日12:21:09过一下 1.01.MySQL课程介绍(Av765670802,P1) 2.02. 基础-课程内容&数据库相关概念(Av765670802,P2) 3.03. 基础-概述-MySQL安装及启动(Av765670802,P3) 4.04. 基础-概述-数据模型(Av765670802,P4) 通过表来存储数据的数据库就叫做关系型数据库 …

QQ云端机器人登录系统php源码开心版

可能很多人不知道这源码有什么用&#xff0c;这款源码主要是针对群机器人爱好者的&#xff0c; 这是一个通过对接挂机宝里面机器人框架的一个网页站点&#xff0c; 用户通过网页登录 QQ 账号至挂机宝里面框架&#xff08;可扫码登录、账密登录、跳转 QQ 快捷登录&#xff09;…

FOC系列(二)----继续学习DRV8301芯片

一、 程序框图 跟随上篇博客咱们继续往下看&#xff0c;下面是芯片内部的程序框图&#xff1a; 1.1 BUCK电路 1.2 内部各电源 1.3 SPI通信、栅极驱动器和时序控制器 1.4 MOSFET驱动电路 1.5 电流采样放大电路 数据手册只是给出了这一部分框图&#xff0c;但是没有更加详细的介…

Azure - 机器学习实战:快速训练、部署模型

本文将指导你探索 Azure 机器学习服务的主要功能。在这里&#xff0c;你将学习如何创建、注册并发布模型。此教程旨在让你深入了解 Azure 机器学习的基础知识和常用操作。 关注TechLead&#xff0c;分享AI全维度知识。作者拥有10年互联网服务架构、AI产品研发经验、团队管理经验…

场效应管器件

在面试硬件方面的工作时&#xff0c;我们通常会被提问模电方面的知识。 场效应管简称FET,有三级&#xff1a;源极(S)、漏极(D)、栅极&#xff08;G&#xff09;&#xff1b;可以实现电压控制电流源&#xff1b;“源极和漏极之间的漏极电流Id&#xff0c;由栅极的负电压进行控制…