HashMap底层源码分析

在这里插入图片描述

HashMap底层源码分析

HashMap主要是用来存放键值对的,它基于哈希表的Map接口实现,是常用的Java集合之一,是非线程安全的。

HashMap可以存放null的Key和value,但是null作为键只能有一个,作为value可以有多个

方法名称说明
V put(K key, V value)添加元素
V remove(Object key)根据键删除键值对元素
void clear()移除所有的键值对元素
boolean containsKey(Object key)判断集合是否包含指定的键
boolean containsValue(Object value)判断集合是否包含指定的值
boolean isEmpty()判断集合是否为空
int size()集合的长度,也就是集合中键值对的个数

HashMap结构

HashMap内部方法

图标为m表示method

image-20240318161136018

HashMap内部类

图标为c表示class

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

HashMap内部属性

图标为f表示field

image-20240318161341292

static class Node<K,V> implements Map.Entry<K,V> {}

HashMap中每个元素都是一个Entry对象,

数组+链表+红黑树

// 表示数组默认的大小 为16
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16// 表示默认的负载因子(加载因子)为0.75
// 当数组元素个数超过0.75*16=12的时候就进行扩容,扩容为原来的2倍空间大小
static final float DEFAULT_LOAD_FACTOR = 0.75f;// 表示HashMap最大的空间为 1073741824
static final int MAXIMUM_CAPACITY = 1 << 30;

构造方法

public HashMap() {this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}

HashMap中的Hash值只与键有关系与值无关

public V put(K key, V value) {return putVal(hash(key), key, value, false, true);
}// 返回键所对应的哈希值
static final int hash(Object key) {int h;return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

>>> 表示无符号右移

扩容机制

调用空参构造的时候,只把属性loadFactor初始化为0.75

剩余的核心源码主要涉及到put操作:

  • 如果当前位置没有值,则直接在数组中添加该键值对,即Node对象
    • 如果数组长度超过其初始长度16*0.75=12的时候,则会进行扩容,扩容成原来的2倍
  • 如果当前位置有值,需要判断和当前新添加的键是否一致: PUT操作
    • 一致:
      • 则进行覆盖更新
    • 不一致:
      • 则在其后以链表的形式进行追加。
      • 当链表的长度达到8【TREEIFY_THRESHOLD】的时候,则会调用treeifyBin()方法,此方法会根据HashMap数组长度来判断是否需要转成红黑树。只有当数组长度大于或者等于64【MIN_TREEIFY_CAPACITY】的情况下,才会执行转换红黑树的操作,以减少搜索时间。否则就只执行resize()方法对数组进行扩容。

get操作:

判断hash和key是否相等,如果是就直接返回,如果不是,需要判断是否是红黑树,是的话按照红黑树的方式进行搜索;如果也不是红黑树就按照链表的顺序从前往后进行遍历查找。

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

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

相关文章

浏览器原理---事件循环

浏览器原理 学习浏览器原理对于我们开发是很有必要的 我们可以了解到浏览器内部工作原理对自己的代码进行优化 进程线程 首先了解进程和线程 进程就就是内存在正在进行的应用程序 在内存中独占一个内存空间 并且进程之间是隔离的 可以看到每个应用都有一个进程 占用空间内存…

刷题之Leetcode206题(超级详细)

206.反转链表 力扣题目链接(opens new window)https://leetcode.cn/problems/reverse-linked-list/ 题意&#xff1a;反转一个单链表。 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL 思路 如果再定义一个新的链表&#xff0…

AI来了,Spring还会远吗?(Spring AI初体验)

目录 一、创建项目二、first demo1、application.properties2、ChatController3、结果 三、个人思考 一、创建项目 官方文档的Getting Started 最低要求&#xff1a;JDK17 阿里云的Server URL&#xff08;https://start.aliyun.com/&#xff09;搜不到Spring AI&#xff0c;…

dbeaver数据库语言编辑器设置jdbc驱动

打开 dbeaver 软件 数据库 -> 驱动管理器 以mysql为例 双击 MySQL -> 库 -> 添加工件 然后 打开maven组件库 官网 找到mysql驱动对应的maven工件地址 复制进去然后确认就行了 参考 大神博客

vue源码解析——diff算法/双端比对/patchFlag/最长递增子序列

虚拟dom——virtual dom&#xff0c;提供一种简单js对象去代替复杂的 dom 对象&#xff0c;从而优化 dom 操作。virtual dom 是“解决过多的操作 dom 影响性能”的一种解决方案。virtual dom 很多时候都不是最优的操作&#xff0c;但它具有普适性&#xff0c;在效率、可维护性之…

基于人脸识别的发型推荐系统代码实现

1.摘要 本文介绍了一个基于人脸识别技术的发型推荐系统的实现与分析。该系统利用Python编程语言和相关库&#xff0c;结合Face人脸识别API&#xff0c;实现了用户上传照片后的性别识别、脸型分析和发型推荐功能。首先&#xff0c;用户通过Tkinter GUI界面选择上传照片&#xff…

Niobe开发板OpenHarmony内核编程开发——定时器

本示例将演示如何在Niobe Wifi IoT开发板上使用cmsis 2.0 接口进行定时器开发 Timer API分析 osTimerNew() /// Create and Initialize a timer./// \param[in] func function pointer to callback function./// \param[in] type \ref osTimerOnce …

C++11 设计模式2. 简单工厂模式

简单工厂&#xff08;Simple Factory&#xff09;模式 我们从实际例子出发&#xff0c;来看在什么情况下&#xff0c;应用简单工厂模式。 还是以一个游戏举例 //策划&#xff1a;亡灵类怪物&#xff0c;元素类怪物&#xff0c;机械类怪物&#xff1a;都有生命值&#xff0…

自动化测试Junit

1.什么是Junit JUint是Java编程语言的单元测试框架&#xff0c;用于编写和运行可重复的自动化测试。 JUnit 促进了“先测试后编码”TDD的理念&#xff0c;强调建立测试数据的一段代码&#xff0c;可以先测试&#xff0c;然后再应用。这个方法就好比“测试一点&#xff0c;编码一…

MAT工具详解

简介 Java自带的JVisualVm可以用来分析Java堆内存&#xff0c;可以用来排查内存泄漏和内存浪费的问题&#xff0c;但是功能不是特别强大&#xff0c; MAT&#xff08;Memory Aanlysis Tool&#xff09;是一款更优的工具。 MAT功能 功能组 全局信息 直方图 按照类的数量倒序…

互联网轻量级框架整合之MyBatis配置详解

MyBatis核心配置文件mybatis-config.xml里有诸多配置项&#xff0c;但常用的就无非就如下这么多 <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTDConfig3.0//EN" "https://mybati…

【力扣】125.验证回文串

刷题&#xff0c;过了真的好有成就感&#xff01;&#xff01;&#xff01; 题解&#xff1a; 根据题目要求&#xff0c;我们需要处理一下几个问题&#xff1a; 将大写字母转变成小写对原来的字符串进行处理&#xff0c;只要字母和数字考虑只有一个和字符串为空的情况 1、将…