JAVA开发(数据类型String和HasMap的实现原理)
在JAVA开发中,使用最多的数据类型恐怕是String 和 HasMap两种数据类型。在开发的过程中我们每天都使用的不亦乐乎。但是相信很多人都没有考虑过String数据类型的实现原理或者说是在数据结构中的存储原理,还有一个就是是HashMap,也很少有人去了解。而且随着jdk版本的发展,这两个类型的实现都一直在优化,而不是一成不变的。有时候只有在找工作面试的时候被面试官问题,然后是一脸蒙蔽。每天都在用,也不用考虑它的原理啊。懂得用不就行了吗?这句话其实对其实也不对,对于实现业务来说,是已经足够了。但是对于对每一行代码做到极致的性能,很多东西还是需要知道它的原理。今天这一节就来梳理梳理String和HashMap的实现原理。
String数据类型:
无处不在的String类型。它位于java jdk 的lang包中,所以无需import就可以直接使用。从源码上看String是被final修饰的,所以它是不能被继承的。
/** ID */private Integer id;/** 用户姓名 */private String userName;/** 登录名 */private String loginName;/** 密码 */private String password;public User() {super();}public User(Integer id, String userName, String loginName, String password) {super();this.id = id;this.userName = userName;this.loginName = loginName;this.password = password;}
由于其使用的广泛性,几乎在每一代的JDK优化升级中都存在对String的优化。
首先在JDK1.7中,我们都知道 String s = "maoheyeren";这个对象是存在常量池中的,JDK1.6的常量池位于方法区。但是到了JDK1.7,就讲常量池优化到了堆中,因为堆的内存更大,方便常量池的扩展。
在JDK1.8和JDK1.8以前,我们可以看一下源码,它的构造函数,可以知道String的下一层是使用char类型存储,但是到了JDK9就使用了byte[]存储,进行了优化减少了存储空间消耗。
所以就是大家平时天天使用的String类型,也不是一层不变的!这个需要注意,算法的优化永无止境!
String对象的创建方式:
String s = "茅河野人是大神";
String s = new String ("茅河野人是大神")
String的源码,实现了序列化、Comparable以及CharSequence接口。
public final class Stringimplements java.io.Serializable, Comparable<String>, CharSequence {// 在JDK1.8中String的值使用char[]数组保存private final char value[];// 使用私有成员变量hash来缓存String的哈希值private int hash; // Default to 0// 构造方法public String(String original) {this.value = original.value;this.hash = original.hash;}public String(char value[]) {this.value = Arrays.copyOf(value, value.length);}...省略
}
还有一个比较关心的问题String到底能存多长的数据。
查看String源代码返回长度的方法,int类型所能表示的最大范围为[0, 2^31-1],实际根据String的两种创建方式还有所不同。
1、使用String s = "茅河野人是大神"; 方式创建对象时javac编译会校验字符串的长度,0xFFFF所能表示的最大长度为2^16=65536,因此这种方式创建的字符串长度会小于65536。而且CONSTANT_Utf8_info型常量的最大长度是是65535 - 1 = 65534个字节,若是中文字符,长度为65535 / 3字节。如果运行时方法区设置的比较小,实际长度可能达不到理论字节。
2、使用new关键字创建对象时,对象在堆内存中分配空间,调用系统的copyOf(),方法,所支持的理论最大长度为Integer.MAX_VALUE,2^31-1;实际情况受虚拟机和堆内存的大小限制。
HashMap数据类型:
HaspMap我们天天往里面put东西,put字符串,put对象,用的时候就get出来,也是从来没思考过里面的实现原理。
JDK1.8 之前 HashMap 的数据结构是 数组+链表 。数组是 HashMap 的主体,单向链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突)。JDK1.8 以后在解决哈希冲突时有了较大的变化,当链表长度大于等于阈值(默认为 8)时,且tab.length>=64时,将链表转化为红黑树,以减少搜索时间。
注意,HashMap的底层数据结构中链表是单向链表,也就是只有next指针,没有prev指针。而LinkedHashMap维护了before、 after、head以及tail。
JDK1.8 之前 HashMap 底层是 数组和链表 结合在一起使用也就是 链表散列。HashMap 通过 key 的 hashCode 经过扰动函数处理过后得到 hash 值,然后通过 (n - 1) & hash值 判断当前元素存放的位置(这里的 n 指的是数组的长度)。
如果当前位置存在元素的话,就判断该元素与要存入的元素的 hash 值以及 key 是否相同,如果相同的话,直接覆盖;不相同就通过拉链法解决冲突。
hashcode的计算算法:
hash(Object key)–扰动函数
所谓扰动函数指的就是 HashMap 的 hash 方法。使用 hash 方法也就是扰动函数是为了防止一些实现比较差的 hashCode() 方法造成的碰撞,换句话说使用扰动函数之后可以减少碰撞。
先获得key的hashCode的值 h,然后 h 和 h右移16位 做异或运算。
实质上是把一个数的低16位与他的高16位做异或运算,因为在 (n - 1) & hash 的计算中,hash变量只有末x位会参与到运算。使高16位也参与到hash的运算能减少冲突。
JDK1.7之前的hashMap存储结构:
到了JDK1.8以后进行额优化,这一点经常有些找事情的面试官会问到。可以看出HashMap以链表的方式存储在数组中,到了JDK1.8以后,以红黑树的方式存储在数组中。
static class Node<K,V> implements Map.Entry<K,V> {final int hash;final K key;V value;Node<K,V> next;Node(int hash, K key, V value, Node<K,V> next) {this.hash = hash;this.key = key;this.value = value;this.next = next;}public final K getKey() { return key; }public final V getValue() { return value; }public final String toString() { return key + "=" + value; }public final int hashCode() {return Objects.hashCode(key) ^ Objects.hashCode(value);}public final V setValue(V newValue) {V oldValue = value;value = newValue;return oldValue;}public final boolean equals(Object o) {if (o == this)return true;if (o instanceof Map.Entry) {Map.Entry<?,?> e = (Map.Entry<?,?>)o;if (Objects.equals(key, e.getKey()) &&Objects.equals(value, e.getValue()))return true;}return false;}}
相关文章:
JAVA开发(数据类型String和HasMap的实现原理)
在JAVA开发中,使用最多的数据类型恐怕是String 和 HasMap两种数据类型。在开发的过程中我们每天都使用的不亦乐乎。但是相信很多人都没有考虑过String数据类型的实现原理或者说是在数据结构中的存储原理,还有一个就是是HashMap,也很少有人去了…...
Hbase 映射到Hive
目录 一、环境配置修改 关闭掉hbase,zookeeper和hive服务 进入hive312/conf 修改hive-site.xml配置, 在代码最后添加配置 将hbase235的jar包全部拷贝到hive312的lib目录,并且所有的是否覆盖信息全部输入n,不覆盖 查看hive312下…...
14_MySQL视图
1. 常见的数据库对象2. 视图概述2.1 使用视图的好处视图一方面可以帮我们使用表的一部分而不是所有的表,另一方面也可以针对不同的用户制定不同的查询视图。比如,针对一个公司的销售人员,我们只想给他看部分数据,而某些特殊的数据…...
做程序界中的死神,斩魂刀始解
标题解读:标题中的死神,是源自《死神》动漫里面的角色,斩魂刀是死神的武器,始解是斩魂刀的初始解放形态,卐解是斩魂刀的觉醒解放形态,也是死神的大招。意旨做程序界中程序员的佼佼者,一步一步最…...
顺序表——“数据结构与算法”
各位CSDN的uu们你们好呀,今天小雅兰的内容是数据结构与算法里面的顺序表啦,在我看来,数据结构总体上是一个抽象的东西,关键还是要多写代码,下面,就让我们进入顺序表的世界吧 线性表 顺序表 线性表 线性表&…...
嵌入式Linux从入门到精通之第十六节:U-boot分析
简介 u-boot最初是由PPCBoot发展而来的,可以引导多种操作系统、支持多种架构的CPU,它对PowerPC系列处理器的支持最为完善,而操作系统则对Linux系统的支持最好目前已成为Armboot和PPCboot的替代品。 特点: 主要支持操作系统:Linux、NetBSD、 VxWorks、QNX、RTEMS、ARTOS、L…...
UART 串口通信
第18.1讲 UART串口通信原理讲解_哔哩哔哩_bilibili 并行通信 一个周期同时发送8bit的数据,占用引脚资源多 串行通信 串行通信的通信方式: 同步通信 同一时钟下进行数据传输 异步通信 发送设备和接收设备的时钟不同 但是需要约束波特率(…...
【硬件】P沟道和N沟道MOS管开关电路设计
场效应管做的开关电路一般分为两种,一种是N沟道,另一种是P沟道,如果电路设计中要应用到高端驱动的话,可以采用PMOS来导通。P沟道MOS管开关电路PMOS的特性,Vgs小于一定的值就会导通,当Vgs<0,即Vs>Vg,管…...
中移杭研一面经历
文章目录 1、常用的Java元注解@Documented@Target@Retention@Override@Deprecated@Inherited@Repeatable@Native2、Java注解的原理3、spring boot starter开发过程1、原理浅谈2、大概步骤3、项目介绍1、常用的Java元注解 @Documented @Documented 是一个标记注解,没有成员变…...
如何成为一名全栈工程师:专业建议与技能要求
作为一名全栈工程师,你需要拥有跨越前端、后端、数据库等多个领域的技能,并能够将它们整合起来构建出完整的应用程序。因此,成为一名全栈工程师需要你掌握多种技术,具备较强的编程能力和系统设计能力。下面,我将从以下…...
MySQL架构篇
一、进阶学习环境说明 1.1 MySQL服务器环境 Linux虚拟机:CentOS 7 MySQL:MySQL5.7.30 在Linux服务器中安装MySQL: ps.如果有自己的云服务器,可忽略前两步,直接进行第三步 1.2 服务器日志文件说明 MySQL是通过文件系统对…...
Redhat7.6安装weblogic10.3.6(超详细,有图文)
一、环境 linux版本:Redhat 7.6 weblogic版本:WLS10.3.6 jdk版本:jdk1.8.0 下载网址:https://www.oracle.com/technetwork/middleware/weblogic/downloads/index.html 1.安装vsftpd服务,将部署环境使用JDK文件和wls服务文件…...
dashboard疏散主机提示报错:无法疏散主机...处理方法、openstack虚拟机状态卡在重启处理方法、openstack在数据库修改虚拟机状态的方法
文章目录dashboard疏散主机提示报错:无法疏散主机...处理方法报错说明【状态卡在reboot状态】解决方法【登录nova数据库修改虚拟机信息】首先获取nova数据库的密码登录nova数据库并做修改验证信息是否修改成功再次迁移并验证报错说明【虚拟机状态error也会导致疏散失…...
力扣:轮转数组(详解)
前言:内容包括:题目,代码实现,大致思路,代码解读 题目: 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3…...
Vue计算属性Computed
30. Vue计算属性Computed 1. 定义 Computed属性是Vue中的一个计算属性,是一种基于其它属性值计算而来的属性值,具有缓存机制,在依赖的属性值发生变化时会重新计算。 使用computed属性可以避免在模板中书写过多的计算逻辑,提高代…...
实验四:搜索
实验四:搜索 1.填格子 题目描述 有一个由数字 0、1 组成的方阵中,存在一任意形状的封闭区域,封闭区域由数字1 包围构成,每个节点只能走上下左右 4 个方向。现要求把封闭区域内的所有空间都填写成2 输入要求 每组测试数据第一…...
本地开发vue项目联调遇到访问接口跨域问题
本地开发vue项目联调遇到访问接口跨域问题 修改本地的localhost 一:按winr打开运行窗口,输入drivers ,然后回车 二:打开etc文件夹,然后用记事本的方式打开里面的hosts文件, 三:这时我们就可…...
Vue键盘事件的使用
前言 在vue中,我们经常会用到键盘事件,不管是我们按下某个键,其实都是一次键盘事件的调用,下面就介绍下Vue中的键盘事件 先写一段代码,这里我选择的键盘事件是keyup,当然用keydown也是没问题的 问题来了,…...
抓包工具fiddler详细使用教程
各位做测试的同学想必对抓包工具fiddler并不陌生,但是很多同学可能没有总结过它的用法,下面我总结了fiddler一些常用的用法。 Web端抓包配置 打开Fiddler,Tools -> Fiddler Options -> HTTPS 配置完后记得要重启Fiddler 选中Decrpt …...
raspberry Pi 连接蓝牙(小爱同学)
参数valueraspberry pi MOdel4B,4Gbbluetooth MOdel小爱同学writeTime2023年 2月11日 下午13:14分raspberry System ModelLinux raspberrypi 5.15.61-v8 #1579 SMP PREEMPT Fri Aug 26 11:16:44 BST 2022 aarch64 GNU/Linux 连接蓝牙 请在小爱同学app上…...
解决launch:program .exe does not exist
二. 程序的运行和调试 1.launch.json 复制下列代码至launch.json,并根据指导做出相对/绝对路径修改 用 IntelliSense 了解相关属性。 {// 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。// 欲了解更多信息,请访问: https://go.micros…...
ETL --事实表
每一个事实表通过表的粒度来定义。事实表的粒度是事件度量的定义。我们必须至始至终按照度量如何在 现实世界中理解来规定事实表的粒度。 所有的事实表包含了一组关联到维表的外键,而这些维表提供了事实表度量的上下文。大多数的事实表还 包括了一个或者多个数值型…...
手工数据采集耗时耗力?Smartbi数据填报实现数据收集分析自动化
企业在日常经营管理过程中,往往需要收集很多内外部的信息,清洗整理后再进行存储、分析、呈现、决策支持等各种作业,如何高效收集结构化数据是企业管理者经常要面对的问题。传统手工的数据采集方式不仅耗费了大量人力时间成本,还容…...
应用实战|微信小程序开发示例--多人聊天互动空间
“超能力”数据库~拿来即用,应用开发人员再也不用为撰写API而发愁。MemFire Cloud 为开发者提供了简单易用的云数据库(表编辑器、自动生成API、SQL编辑器、备份恢复、托管运维),很大地降低开发者的使用门槛。 本示例是…...
css:使用filter和backdrop-filter实现高斯模糊效果
背景 今天接到一个需求是,使用高斯模糊的效果对一个页面进行模糊处理,正好借这个机会来整理一下 css3 中高斯模糊的两个 API API介绍 filter 说明: 该 API 是一个过滤器,不仅能实现高斯模糊,还有很多比如颜色偏移、…...
科技大势怎么看 2023怎么干?
2023年,科技的走向依旧是世界各国的关注重点,各国在纷纷设立自己的科技战略目标外,还在潜心研究不同技术领域的科技趋势,试图通过科技占据国际竞争的制高点。 随着我国深入实施创新驱动发展战略,推动产业结构优化升级&…...
盘点曾经很火但消失了的8个软件
目录 1、飞信 3、暴风影音 4、千千静听 5、虾米音乐 6、快车下载 7、人人网 8、QQ农场 今天小编给大家分享曾经很火但消失了的8个软件,你都用过吗? 1、飞信 飞信是中国移动通信集团公司推出的一款短信、语音、视频通信应用程序。它于2007年推出&a…...
安卓 Frament + ViewPager使用示例
1. 组成架构 整个架构被包在一个外部Fragment之中,也可以放在一个Activity之中,随意。外部的fragment包含了两个组件,即途中的ViewPager和TabLayoutViewPager要套上一个FragmentStatePagerAdapter ,适配器负责new出一个个fragment…...
【银行测试】必看的四类题型:这可是最经典的一套题目了
目录:导读 一、根据题目要求写出具体LINUX操作命令 二、JMETER题目 三、根据题目要求写出具体SQL语句 四、测试案例设计题 金三银四面试面对大厂面试官提问,如何回答:花3天背完这100道软件测试面试题!银行测试的offer还不是手…...
跨源资源共享(CORS)-亲测理解,以及对http的状态,参数的理解和使用,对预检请求的触发和解决
跨源资源共享(CORS)-亲测理解,以及对http的状态,参数的理解和使用 跨源资源共享(CORS,或通俗地译为跨域资源共享)是一种基于HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的…...
photolux wordpress/jsurl转码
MKLINK [[/D] | [/H] | [/J]] Link Target/D 创建目录符号链接。黙认为文件符号链接。/H 创建硬链接,而不是符号链接。/J 创建目录联接。Link 指定新的符号链接名称。Target 指定新链接引用的路径(相对或绝对)。mklink /j D:\apache-tomcat-7.0.3…...
稳定免费域名/seo推广培训资料
题目链接:https://ctf.bugku.com/challenges 题解: 打开题目 得到一段PHP代码 该代码中相关函数知识点链接如下:extract函数:http://www.w3school.com.cn/php/func_array_extract.aspisset函数:http://php.net/manual/…...
大淘客做网站视频/品牌推广平台
用delphi来制作一些客户端小工具还是比较方便的。我们通常在做一个软件的时候,首先要考虑的是窗体布局和窗体之间的互相调用问题。下面就是主从窗体的实施步骤:第一步,打开【Delphi7】,新建一个Delphi工程,新建一个空白窗体命名为…...
学校网站模板 中文/近三天时政热点
摘要:ERP物理机迁移至阿里云实践 机房选型 随着公司的不断发展,业务量逐渐增大,对信息化的要求也越来越高,随之对信息部的要求也越来越多,为此公司决定对现有的信息系统进行升级改造.ERP物理机迁移至阿里云实践一、机房选型随着公司的不断发展,业务量逐渐增大,对信息…...
做电商网站公司/app推广拉新一手渠道代理
jQuery.fileDownload 成功回调失败原因 jQuery 的文件下载插件非常好用,突然发现失败后回调函数可以实现,成功后的回调函数总是失败,如何测试都不行 原因不在前端 是在请求时后台有没有返回cookie值 只有后台返回cookie值时成功回调函数才…...
连云港专业网站制作/引擎搜索对人类记忆的影响
IE9空白页,ie9打开后空白,正解,点选工具--INTERNET选项--高级--加速的图形--勾选不用GPU即可,好多人说什么选项卡,什么网络链接不正常都是瞎扯,很简单的。转载于:https://www.cnblogs.com/lovewuhan/archiv…...