Java集合面试题:HashMap源码分析
文章目录
- 一、HashMap源码
- 二、HashMap数据结构模型图
- 三、HashMap中如何确定元素位置
- 四、关于equals与hashCode函数的重写
- 五、阅读源码
- 基本属性
参考文章:史上最详细的 JDK 1.8 HashMap 源码解析
参考文章:Hash详解
参考文章:hashCode源码分析
参考文章:hashCode方法
参考文章:Java 细品 重写equals方法 和 hashcode 方法
参考文章:native
参考文章:HashMap中确定数组位置为什么要用hash进行扰动
一、HashMap源码
JDK官方文档源码,方便后面对照学习
二、HashMap数据结构模型图
JDK1.8对HashMap进行了比较大的优化,底层实现由之前的“数组+链表”改为“数组+链表+红黑树”。JDK1.8的HashMap的数据结构如下图所示,当链表结点较少时仍然是以链表存在,当链表结点较多时(大于8)会转为红黑树。
三、HashMap中如何确定元素位置
- 通过key.hashcode(),根据key获得hashcode值
- 通过扰动函数hash(),根据hashcode获得hash值
- 通过**(n-1)&hash**判断当前元素存放的位置,这里的n指的是数组的长度
- 上面三个“通过”才可以获取真正意义上hashCode,即table的位置。
- 如果当前位置存在元素的话,equals() 就判断该元素与要存入的元素的hash值以及key是否相同,如果相同的话,直接覆盖,不相同就通过拉链法解决冲突
其中jdk1.8中扰动函数hash的源码:
static final int hash(Object key) {int h;// key.hashCode():返回散列值也就是hashcode// ^ :按位异或// >>>:无符号右移,忽略符号位,空位都以0补齐return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
其中看到在获得hash值时将key的hashCode异或上其无符号右移16位,Hashmap这么做原因:
防止一些实现比较差的 hashCode() 方法,使用扰动函数之后可以减少碰撞,进一步降低hash冲突的几率。
四、关于equals与hashCode函数的重写
首先我们必须知道,如果我们要使用HashMap来添加以对象作为key的键值对,那么就必须重写equals和hashCode函数。具体看 “三、HashMap中如何确定元素位置。”
我们先来看一下,没有重写的hashCode和equals的源码,不用怀疑,这就是全部源码。
//返回对象在JVM中的32位内存地址,native解释请看参看文章
public native int hashCode();
//比较两个对象的32位内存地址
public boolean equals(Object obj) { return (this == obj); }
为什么我们需要重写hashCode和equals呢?不重写会怎样呢?看看下面示例
public class Student { private String name;private Integer age;
}/*我现在用同一个人(John,21),创建两个对象student1和student2。由于这两个对象是同一个人,所以这两个对象是相等的,但是结果却是false。
*/
public static void main(String[] args) {Student student1 = new Student();student1.setName("John");student1.setAge("21");Student student2 = new Student();student2.setName("John");student2.setAge("21");System.out.println(student1.equals(student2)); //falseSystem.out.println(student1.hashCode() == student2.hashCode()); //false
}
明明是同一个人(John,22),为什么两个对象就不相等呢?因为我们认为的两个对象相等是根据属性的值来判断的,例如student1和student2都是name=John、age=21,那么我就认为他们是相等的。但是我们再来看看Object的hashCode和equals源码,它才不管student1和student2的属性值是否相等,只要两个对象内存地址不一样就是不相等。
这时候我们就知道要重写hashCode和equals,那么我们重写这两个方法的原则是什么?
- hashCode重写:要根据类的属性值来生成hashCode
- equals重写:要根据类的属性值来进行判断
@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;boolean nameCheck=false;boolean ageCheck=false;if (this.name == student.name) {nameCheck = true;} else if (this.name != null && this.name.equals(student.name)) {nameCheck = true;}if (this.age == student.age) {ageCheck = true;} else if (this.age != null && this.age.equals(student.age)) {ageCheck = true;}if (nameCheck && ageCheck){return true;}return false;
@Overridepublic int hashCode() {int result = 17;result = 31 * result + name.hashCode();result = 31 * result + age;return result;}
现在再来测试一下
public static void main(String[] args) {Student student1 = new Student();student1.setName("John");student1.setAge("21");Student student2 = new Student();student2.setName("John");student2.setAge("21");System.out.println(student1.equals(student2)); //trueSystem.out.println(student1.hashCode() == student2.hashCode()); //true
}
重写equals和hashCode,是指我们在开发项目的时候,要根据自己创建对象来重写。例如我创建了Student类里面有name,id,那么我在重写equals和hashCode时候就要有对name和id的比较判断,如果我创建了Animal类里面有age,owner,那么我在重写equals和hashCode时候就要有对age和owner的比较判断
其实在java 7 有在Objects里面新增了我们需要重新的这两个方法,所以我们重写equals和hashCode还可以使用java自带的Objects,如:
@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Pig pig = (Pig) o;return Objects.equals(name, pig.name) &&Objects.equals(age, pig.age);}@Overridepublic int hashCode() {return Objects.hash(name, age);}
那么如果还是觉得有点麻烦呢? 那就使用lombok的注解,让它帮我们写,我们自己就写个注解!
@EqualsAndHashCode(exclude = {"Age"}) //设置重写不包含的字段
public class Student{private String name;private Integer age;
}
五、阅读源码
HashMap在重点其实就是第三、四点,这里对源码再解读一下。
基本属性
// 默认容量16
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // 最大容量
static final int MAXIMUM_CAPACITY = 1 << 30; // 默认负载因子0.75
static final float DEFAULT_LOAD_FACTOR = 0.75f; // 链表节点转换红黑树节点的阈值, 当链表结点大于8时,转成红黑树结点
static final int TREEIFY_THRESHOLD = 8; // 红黑树节点转换链表节点的阈值, 当红黑树结点小于7时,转成链表结点
static final int UNTREEIFY_THRESHOLD = 6; // 转红黑树时, table的最小长度
static final int MIN_TREEIFY_CAPACITY = 64; // 链表节点, 继承自Entry
static class Node<K,V> implements Map.Entry<K,V> { final int hash;final K key;V value;Node<K,V> next;// ... ...
}// 红黑树节点
static final class TreeNode<K,V> extends LinkedHashMap.Entry<K,V> {TreeNode<K,V> parent; // red-black tree linksTreeNode<K,V> left;TreeNode<K,V> right;TreeNode<K,V> prev; // needed to unlink next upon deletionboolean red;// ...
}
相关文章:
Java集合面试题:HashMap源码分析
文章目录一、HashMap源码二、HashMap数据结构模型图三、HashMap中如何确定元素位置四、关于equals与hashCode函数的重写五、阅读源码基本属性参考文章:史上最详细的 JDK 1.8 HashMap 源码解析参考文章:Hash详解参考文章:hashCode源码分析参考…...
华为OD机试 - 数组合并(Python),真题含思路
数组合并 题目 现在有多组整数数组, 需要将他们合并成一个新的数组。 合并规则, 从每个数组里按顺序取出固定长度的内容合并到新的数组中, 取完的内容会删除掉, 如果该行不足固定长度或者已经为空, 则直接取出剩余部分的内容放到新的数组中, 继续下一行。 如样例 1, 获得长度…...
Vue2创建移动端项目
一、Vscode Vscode 下载安装以及常用的插件 1、Vscode 下载 下载地址:Vscode 中文语言插件 搜索 chinese 主题 Atom 主题 文件图标主题 搜索 icon 源代码管理插件GitLens 搜索 GitLens Live Server _本地服务器 搜索 Live Server Prettier - Code formatt…...
PorterDuffXfermode与圆角图片
版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl 圆角图片 在项目开发中,我们常用到这样的功能:显示圆角图片。 这个是咋做的呢?我们来瞅瞅其中一种实现方式 /*** param bitmap 原图* p…...
如何准备大学生电子设计竞赛
大学生电子设计竞赛难度中上,一般有好几个类型题目可以选择,参赛者可以根据自己团队的能力、优势去选择合适自己的题目,灵活自主空间较大。参赛的同学们可以在暑假好好学习相关内容,把往年的题目拿来练练手。这个比赛含金量还是有…...
【Java容器(jdk17)】ArrayList深入源码,就是这么简单
ArrayList深入源码一、ArrayList源码解析1. MIXIN 的混入2. 属性说明3. 构造方法4. 其他方法(核心)iterator 和 listIterator 方法add方法remove 方法sort方法其他二、ArrayList 为什么是线程不安全的?体现哪些方面呢?三、ArrayLi…...
【Java 面试合集】简述下Java的三个特性 以及项目中的应用
简述下Java的特征 以及项目中的应用 1. 概述 上述截图中就是Java的三大特性,以及特性的实现方案。接下来就每个点展开来说说 2. 封装 满足:隐藏实现细节,公开使用方法 的都可以理解为是封装 而实现封装的有利手段就是权限修饰符了。可以根据…...
git基本概念图示【学习】
基本概念工作区(Working Directory)就是你在电脑里能看到的目录,比如名字为 gafish.github.com 的文件夹就是一个工作区本地版本库(Local Repository)工作区有一个隐藏目录 .git,这个不算工作区,…...
微前端qiankun架构 (基于vue2实现)使用教程
工具使用版本 node --> 16vue/cli --> 5 创建文件 创建文件夹qiankun-test。 使用vue脚手架创建主应用main和子应用dev 主应用 安装 qiankun: yarn add qiankun 或者 npm i qiankun -S 使用qiankun: 在 utils 内创建 微应用文件夹 microApp,在该文件夹…...
记录robosense RS-LIDAR-16使用过程3
一、wireshark抓包保存pcap文件并解析ubuntu18安装wireshark,参考下面csdn教程,官网教程我看的一脸蒙(可能英语太差)https://blog.csdn.net/weixin_46048542/article/details/121730448?spm1001.2101.3001.6650.2&utm_medium…...
【博学谷学习记录】大数据课程-学习第七周总结
Hadoop配置文件修改 Hadoop安装主要就是配置文件的修改,一般在主节点进行修改,完毕后scp下发给其他各个从节点机器 文件中设置的是Hadoop运行时需要的环境变量。JAVA_HOME是必须设置的,即使我们当前的系统中设置了JAVA_HOME,它也…...
154、【动态规划】leetcode ——494. 目标和:回溯法+动态规划(C++版本)
题目描述 原题链接:494. 目标和 解题思路 (1)回溯法 本题的特点是nums中每个元素只能使用一次,分别试探加上nums[index]和减去nums[index],然后递归的遍历下一个元素index 1。 class Solution { public:int res …...
MySQL-窗口函数
窗口函数概念常用窗口函数聚合窗口函数专用窗口函数语法OVER子句window_specwindow_name (命名窗口)partition_clause 分区order_clause 排序frame_clause 范围 (指定窗口大小)使用限制练习准备概念 窗口函数对一组查询执行类似于聚合的操作。然而&#…...
【C++设计模式】学习笔记(1):面向对象设计原则
目录 简介面向对象设计原则(1)依赖倒置原则(DIP)(2)开放封闭原则(OCP)(3)单一职责原则(SRP)(4)Liskov替换原则(LSP)(5)接口隔离原则(ISP)(6)优先使用对象组合,而不是类继承(7)封装变化点(8)针对接口编程,而不是针对实现编程结语简介 Hello! 非常感谢您阅读海…...
[测开篇]设计测试用例的方法如何正确描述Bug
文章目录为什么测试人员要写测试用例?怎样设计测试用例?(总的方面)1.基于需求设计测试用例(总的方面) 2.页面(总的方面) 3.非功能性测试(具体方面) 4.1 等…...
设计模式学习笔记--单例、建造者、适配器、装饰、外观、组合
以下内容根据以下网址及相关视频整理:Android设计模式之单例模式_谬谬清不给我取名字的博客-CSDN博客_android 单例模式 Android设计模式--单例模式的六种实现和单例模式讲解Volatile与Synchronized相关的并发_龙腾腾的博客-CSDN博客_android 单例 volatile java …...
English Learning - Day5 L1考前复习 2023.2.10 周五
English Learning - Day5 L1考前复习 2023.2.10 周五1 单选题:She has the face _________.2 单选题: The goals ________ he fought all his life no longer seemed important to him.3 单选题:Sales director is a position ______ communi…...
C. Prepend and Append
time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Timur initially had a binary string†† s� (possibly of length 00). He performed the following operation several (possibly zero)…...
javassm超市在线配送管理系统
为了解决用户便捷地在网上购物,本文设计和开发了一个超市管理系统。本系统是基于web架构设计,SSM框架 ,使用Mysql数据库管理,综合采用JSP模式来完成系统的相关功能。主要实现了管理员与用户的注册与登陆,个人中心、用户…...
Scratch少儿编程案例-多模式贪吃蛇(无尽和计时)
专栏分享 点击跳转=>Unity3D特效百例点击跳转=>案例项目实战源码点击跳转=>游戏脚本-辅助自动化点击跳转=>Android控件全解手册点击跳转=>Scratch编程案例👉关于作者...
谷歌蜘蛛池怎么搭建?Google蜘蛛池可以帮助谷歌排名吗?
本文主要分享关于谷歌蜘蛛池的搭建疑问,以及Google对谷歌排名的影响到底有多大。 本文由光算创作,有可能会被剽窃和修改,我们佛系对待这种行为吧。 谷歌蜘蛛池怎么搭建? 答案是:需要一个内链外链体系复杂的站群系统…...
Kubernetes集群-部署Java项目
Kubernetes集群-部署Java项目(SSG) k8s部署项目java流程图 第一步 打包制作镜像 打包 java源码: application.properties #在有pom.xml的路径下执行 mvn clean package制作镜像: 将刚才打包后的文件夹传到,装有dock…...
English Learning - Day54 作业打卡 2023.2.8 周三
English Learning - Day54 作业打卡 2023.2.8 周三引言1. 就算你不喜欢喝酒,也请尝一杯吧。2. 便纵有千种风情,更与何人说?——柳永《雨霖铃》 (来,挑战一下古诗词)3. 虽然忙,我也要参加会议。4. 无论发生什么…...
【Unity题】 1.矩阵旋转,欧拉旋转,四元数旋转各自的优缺点。2.StringBuilder和String的区别
1.矩阵旋转,欧拉旋转,四元数旋转各自的优缺点 矩阵旋转,欧拉旋转,四元数旋转是三种不同的旋转表示方法,下面是它们各自的优缺点: 矩阵旋转: 优点: 1.可以方便地实现复合旋转&…...
【C++面试问答】搞清楚深拷贝与浅拷贝的区别
问题 深拷贝和浅拷贝的区别是面试中的常见问题之一,对于不同的编程语言,这个问题的回答可能稍有差别,下面我们就来探索一下它们之间的异同吧。 先来看看在JavaScript对象的深拷贝与浅拷贝的区别: 浅拷贝:只是复制了…...
day10_面向对象基础
今日内容 零、 复习昨日 一、面向对象的概念 二、面向对象编程 三、内存图 零、 复习昨日 见晨考题 每日一数组题 写一个方法 用于合并两个int类型的数组 合并法则如下 {1,2,5,8,9}{1,3,0}---->{1,2,5,8,9,1,3,0} package com.qf.array;import java.util.Arrays;/*** --- 天…...
电影订票网站的设计与开发
技术:Java、JSP等摘要:随着科技的发展,时代的进步,互联网已经成为了人们生活中不可缺少的一部分,网上购物已然是一种时代的象征。纵观市场,电影行业的发展尤为迅速,电影种类和数量的增多导致客流…...
seata【SAGA模式】代码实践(细节未必完全符合saga的配置,仅参考)
seata SAGA模式: 代码仍然是上一篇AT模式的代码:AT模式 不需要undo_log表 下面开始: 首先,saga模式依靠状态机的json文件来执行整个流程,其中的开始节点的服务即TM,然后状态机需要依靠三张表࿰…...
面试题:Java锁机制
java对象包含了三个部分:对象头,实例数据和对齐填充。对象头又存放了:markWord和class point。classpoint :指向方法区,当前对象的类信息数据。markword:存储了很多和当前对象运行时的数据:例如…...
Springboot Web开发
文章目录一. 静态资源访问1. 配置静态资源访问前缀2. 修改默认静态资源存放目录3. Webjars4. 欢迎页支持5. 自定义Favicon二. 请求处理1. 路径变量2. 请求头处理3. 查询字符串处理4. 获取Cookie的值5. 获取请求体的值6. 获取请求域中的数据7. 矩阵变量一. 静态资源访问 只要静…...
网站上动态图片怎么做/网站维护一般都是维护什么
http://www.lydsy.com/JudgeOnline/problem.php?id2020 和背包差不多 同样滚动数组 f[j]表示当前位置j份食物的最小价值 f[j]min(f[j-l]l*c) 1<l<f 而且在每一步走的时候 f[j]j 然后就行了。。 #include <cstdio> #include <cstring> #include <cmath>…...
区块链做网站都有哪些内容呢/电商平台有哪些
尝鲜使用Kotlin写了一段时间Android。说大幅度的减少了Java代码一点不夸张。用Java的时候动不动就new一个OnClickListener()匿名类,动不动就类型转换的地方都可以省下很多。更不用说特殊的地方使用data class更是少些不知道多少代码。 Jetbrains给Android带来的不仅…...
江苏住房和城乡建设厅官方网站6/百度推广怎么优化排名
个人测试结论备忘 环境:ubuntu server 9.04 nginxmysqlfastcgi 1、单独Zend Optimizer优化: 测试结果很不稳定,偏差很大,加速并不多。 2、单独eAccelerator(做为Zend扩展)优化: 测试结果稳定&a…...
网页制作公司地址/班级优化大师的优点
从sqlite数据库导入到mysql数据库实例从sqllite中导出数据文件库XX.sql的文件。导入到mysql数据库中。键入命令: source /smb/works/mysql.sql出现很多如下的错误:You have an error in your SQL syntax; check the manual thatcorresponds to your Mari…...
上海网站建设 网页做/seo公司系统
通过前期的诸多准备,现在终于要摩拳擦掌大干一番了啊!磨刀不误砍柴工啊,通过那么辛苦的前期准备,可以见识一下LiveMigration的魅力了。想一想可以不间断服务就能迁移虚拟机,物理机宕机了虚拟机照样跑。哇!这…...
dnf网站上怎么做商人/上海今天最新新闻10条
一、关键字执行顺序1、查询中用到的关键词主要包含六个,并且他们的顺序依次为 :select--from--where--group by--having--order by 其中select和from是必须的,其他关键词是可选的。这六个关键词的执行顺序,与sql语句的书写顺序并不…...