手撕HashMap底层源码 (JDK1.7版本的HashMap)

day27

集合框架

标绿已经学习底层,深入底层主要是研究实现类底层集合框架

手撕HashMap底层源码

JDK1.7版本的HashMap

切换版本

原因:jdk1.7和jdk1.8的HashMap不同(头插法/尾插法)

首先如果没有jdkjre1.7,就安装jdkjre1.7,之后eclipse中添加
添加jre1.7
由于前期都用的jdk1.8版本,所有要再切换jdk1.7版本
转换jre1.7

场景:
		HashMap<Student, String> map = new HashMap<>();
		map.put(new Student("小小", '男', 23, "2401", "001"), "拍电影");
		map.put(new Student("大大", '男', 20, "2401", "002"), "打篮球");
		map.put(new Student("奇男子", '男', 21, "2401", "003"), "玩游戏");
		map.put(new Student("奇男子", '男', 21, "2401", "003"), "写代码");
		map.put(null, "aaa");
		map.put(null, "bbb");
遍历:数组从头到尾遍历
        null=bbb
        奇男子	男	21	2401	003=写代码
        大大	男	20	2401	002=打篮球
        小小	男	23	2401	001=拍电影
补充:NaN - Not a Number
//		Float float1 = new Float("0.0f");
//		Float float2 = new Float("0.0f");
//		Float result = float1/float2;
//		System.out.println(result);//NaN
//		System.out.println(Float.isNaN(result));
//		HashMap<Student, String> map = new HashMap<>(16,result);

底层

public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>{
    //默认初始化容量 -- 必须是2的幂
    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;
    //最大容量
    static final int MAXIMUM_CAPACITY = 1 << 30;
    //默认的负载因子(静态属性共享,也可以添加自定义负载因子)
    static final float DEFAULT_LOAD_FACTOR = 0.75f;
    //空内容的数组
    static final Entry<?,?>[] EMPTY_TABLE = {};
    //hash数组/hash表
    transient Entry<K,V>[] table = (Entry<K,V>[]) EMPTY_TABLE;//EMPTY_TABLE
    //元素个数
    transient int size;//0
    //阈值(数组长度*负载因子)
    int threshold;//16
    //负载因子
    final float loadFactor;//0.75f
    //外部操作数(记录添加、删除的次数)
    transient int modCount;//0
    //hash种子数
    transient int hashSeed = 0;//0
    
    public HashMap() {
        this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
    }
    
    //initialCapacity - 16
    //loadFactor - 0.75f
    public HashMap(int initialCapacity, float loadFactor) {
        //判断数组初始化容量如果小于0,就报错
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal initial capacity: " +
                                               initialCapacity);
        
        //判断数组容量大于最大容量,就把最大容量赋值给初始化容量
        if (initialCapacity > MAXIMUM_CAPACITY)
            initialCapacity = MAXIMUM_CAPACITY;
        
        //判断负载因子如果小于等于0 或者 判断负载因子不是一个数字,就报错
        if (loadFactor <= 0 || Float.isNaN(loadFactor))//NaN - Not a Number
            throw new IllegalArgumentException("Illegal load factor: " + loadFactor);

        this.loadFactor = loadFactor;
        threshold = initialCapacity;
        init();//作用:让子类去重写(LinkedHashMap),子类做初始化功能
    }
    
    void init() {
    }
    
    //映射关系类/节点类
    static class Entry<K,V> implements Map.Entry<K,V> {
        final K key; --------- key
        V value; ------------- value
        Entry<K,V> next; ----- 下一个节点的地址
        int hash; ------------ key的hash值

        Entry(int h, K k, V v, Entry<K,V> n) {
            value = v;
            next = n;
            key = k;
            hash = h;
        }
     }
}
HashMap理解图

HashMap理解图

init();的作用

让子类去重写(LinkedHashMap),子类做初始化功能
伪代码理解:LinkedHashMap调用父类的有参构造,int()返过来调用子类LinkedHashMap中重写的int();
int伪代码

面试题

JDK1.7版本的HashMap是什么数据结构?

一维数组+单向链表

什么是Hash桶?

hash数组里的单向链表

什么是hash碰撞/hash冲突?

key的hash值一致,在数组中的下标上有重复的元素

HashMap默认数组长度是多少?

长度是1<<4,就是16的长度

HashMap数组的长度为什么必须是2的幂?

??????(涉及后面线程安全内容先搁置)

HashMap数组的最大容量是多少?

1<<30

HashMap数组的最大容量为什么是1<<30?

最大容量为int类型,int类型的最大值是2的31次方-1

因为HashMap数组必须是2的幂,1<<30是int取值范围内最大的2的幂的数字

所以HashMap数组最大容量是1<<30

HashMap默认负载因子是多少?

0.75f

HashMap的负载因子的作用是什么?

数组长度*负载因子 等于 阈值,阈值是控制何时扩容

HashMap数组默认的负载因子为什么是0.75f?

取得了空间和时间的平衡

如果负载因子过大(如:1),会导致数组全部装满后,再扩容。利用了空间,浪费了时间

如果负载因子过小(如:0.2),会导致数组装了一点点元素,就扩容。利用了时间,浪费了空间

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

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

相关文章

mysql数据库备份学习笔记

数据库备份 方法1 物理备份&#xff1a;xtrabackup 方法2 逻辑备份 mysqldump 参考备份与恢复的方法&#xff1a; 【MySql】Mysql之备份与恢复_mysql数据库备份与还原-CSDN博客 可以借鉴的物理备份&#xff1a; 思路是 先做一次全量备份&#xff0c;然后每天做一次增量备份…

从大模型到Agentscope——进阶: 容错机制与构建多模态应用

文章目录 容错机制与构建多模态应用高鲁棒的容错机制鲁棒性的挑战可访问性错误规则可解错误&模型可解错误不可解错误 设计理念&#xff1a;多模态 容错机制与构建多模态应用 高鲁棒的容错机制 鲁棒性的挑战 可访问性错误 默认重新调用三次并把报错给打印出来 规则可解错误…

嵌入式单片机学习思路感想分享

今天看到了一个提问,原话如下: 曾经干了8年单片机工程师,对工程师从入门,到入行,再到普通,再到高级,整个路径还算清晰,比如什么阶段,会碰到什么瓶颈,怎么突破,我都经历过。 这个同学,有个典型的问题,就是学得太多且杂了,估计稍微复杂点的项目,做不出来。 现在…

长期护理保险可改善老年人心理健康 | CHARLS CLHLS CFPS 公共数据库周报(3.6)...

欢迎报名2024年“真实世界临床研究”课程&#xff01; 本周郑老师开讲&#xff1a;“真实世界临床研究”培训班&#xff0c;3月16-17日两天&#xff0c;欢迎报名&#xff01; CHARLS公共数据库‍ CHARLS数据库简介中国健康与养老追踪调查(China Health and Retirement Longitud…

.NET高级面试指南专题十八【 外观模式模式介绍,提供了简化的接口,隐藏系统的复杂性】

介绍&#xff1a; 外观模式是一种结构设计模式&#xff0c;它提供了一个统一的接口&#xff0c;用于访问子系统中的一组接口。外观模式定义了一个高层接口&#xff0c;使得子系统更容易使用。 原理&#xff1a; 外观类&#xff08;Facade Class&#xff09;&#xff1a;提供了一…

电脑芯片维修费用、价格方面的处理方法有哪些?

电脑使用时间长了&#xff0c;难免会出现这样或那样的问题。 笔者整理了一些关于电脑芯片维修费用和价格的参考资料&#xff0c;以及简单的处理方法&#xff0c;供大家了解和学习&#xff1a; 1、笔记本电脑芯片维修&#xff1a; 首先检查电脑系统是否完好。 如果是系统软故障…

【Qt】常用控件或属性(1)

需要云服务器等云产品来学习Linux可以移步/-->腾讯云<--/官网&#xff0c;轻量型云服务器低至112元/年&#xff0c;新用户首次下单享超低折扣。 目录 一、QWidget属性一览 二、控件button、属性enabled(可用状态) 三、属性geometry(修改位置和尺寸) 1、QRect类型的结…

数字化转型导师坚鹏:金融机构数字化运营

金融机构数字化运营 课程背景&#xff1a; 很多金融机构存在以下问题&#xff1a; 不清楚数字化运营对金融机构发展有什么影响&#xff1f; 不知道如何提升金融机构数字化运营能力&#xff1f; 不知道金融机构如何开展数字化运营工作&#xff1f; 课程特色&#xff1a;…

Vue2 引入自己下载的SVG图像的方式

Vue2 引入下载的SVG图像的方式 Step 1&#xff1a;安装依赖 npm i svg-sprite-loader --saveStep 2&#xff1a;创建文件路径 // index.js import Vue from vue import SvgIcon from /components/SvgIcon// svg component// register globally Vue.component(svg-icon, Svg…

PHP序列化基础知识储备

一、序列化与反序列化 1、概念 PHP中的序列化是指将复杂的数据类型转换为可存储或可传输的字符串&#xff0c;而反序列化则是将这些字符串重新转换回原来的数据类型。 序列化通常使用 serialize() 函数完成&#xff0c;它可以将数组、对象、字符串等复杂数据类型压缩到一个字…

在Linux/Ubuntu/Debian中使用7z压缩和解压文件

要在 Ubuntu 上使用 7-Zip 创建 7z 存档文件&#xff0c;你可以使用“7z”命令行工具。 操作方法如下&#xff1a; 安装 p7zip&#xff1a; 如果你尚未在 Ubuntu 系统上安装 p7zip&#xff08;7-Zip 的命令行版本&#xff09;&#xff0c;你可以使用以下命令安装它&#xff1a;…

数据结构:堆

堆的概念 1.堆是一个完全二叉树 2.小堆(任何一个父亲<孩子),大堆(任何一个父亲>孩子) 堆的结构 物理结构:数组 逻辑结构:二叉树 #pragma once #include<assert.h> #include<iostream> typedef int HPDataType; typedef struct Heap {HPDataType* _a;int…

手写Mybatis自动填充插件

目录 一、Mybatis插件简介&#x1f959;二、工程创建及前期准备工作&#x1f96b;实现代码配置文件 三、插件核心代码实现&#x1f357;四、测试&#x1f953; 一、Mybatis插件简介&#x1f959; Mybatis插件运行原理及自定义插件_简述mybatis的插件运行原理,以及如何编写一个…

Java8 Stream流详解

文章目录 概念和特点基本流程常见操作过滤&#xff08;filter&#xff09;映射&#xff08;map&#xff09;收集&#xff08;collect&#xff09;归约&#xff08;reduce&#xff09;扁平映射&#xff08;flatMap&#xff09; java案例详解注意事项 概念和特点 Java中的Stream是…

Qt 线程池 QThreadPool

一.Qt 线程池 QThreadPool介绍 Qt线程池是一种管理多个线程的并发编程模型&#xff0c;通过使用线程池可以提高性能、控制并发度、提供任务队列和简化线程管理。 在Qt中&#xff0c;线程池的使用主要涉及以下几个步骤&#xff1a; 创建任务类&#xff1a;需要定义一个任务类&am…

PGA高端项目:FPGA基于GS2971+GS2972架构的SDI视频收发,提供3套工程源码和技术支持

目录 1、前言免责声明 2、相关方案推荐本博已有的 SDI 编解码方案本方案的SDI接收图像缩放应用本方案的SDI接收纯verilog图像缩放纯verilog多路视频拼接应用本方案的SDI接收HLS图像缩放HLS多路视频拼接应用本方案的SDI接收OSD动态字符叠加输出应用本方案的SDI接收HLS多路视频融…

AJAX 03 XMLHttpRequest、Promise、封装简易版 axios

AJAX 学习 AJAX 3 原理01 XMLHttpRequest① XHR 定义② XHR & axios 关系③ 使用 XHR④ XHR查询参数案例&#xff1a;地区查询&#xff08;URLSearchParams&#xff09;⑤ XHR数据提交 POST 02 PromisePromise 使用Promise - 三种状态案例&#xff1a;使用Promise XHR 获取…

sqllab第二十一关通关笔记

知识点&#xff1a; 错误注入 最大长度为32超过需要利用截取函数分段读取cookie注入base64加密会保留符号的原始属性 通过admin admin进行登录发现和第二十关显示的内容一样&#xff0c;猜测应该还是cookie注入&#xff1b; 直接截取带有cookie的数据包&#xff0c;发现uname…

SpringBoot异常:类文件具有错误的版本 61.0, 应为 52.0的解决办法

问题&#xff1a; java: 无法访问org.mybatis.spring.annotation.MapperScan 错误的类文件: /D:/Program Files/apache-maven-3.6.0/repository/org/mybatis/mybatis-spring/3.0.3/mybatis-spring-3.0.3.jar!/org/mybatis/spring/annotation/MapperScan.class 类文件具有错误的…

YOLO_项目环境配置

YOLOv5官方项目地址 https://github.com/ultralytics/yolov5 下载 5.0和1.0源码 5.0 master-Tags-v5.0 Code-Download.ZIP 切换到1.0下载 解压缩提取 打开V5.0 使用Pycharm打开V5.0的文件夹 环境配置 参考 http://t.csdnimg.cn/Zdfh2 http://t.csdnimg.cn/Nqkwr 然后在Pyc…