深入理解HashMap(文末附带源码)

深入理解HashMap原理()——HashMap源码解析(JDK 1.8) 介绍 HashMap原理是JAVAAndroid面试中经常会遇到的问题,这篇文章将通过HashMap在JDK1.71.8 中的源码来解析HashMap的原理。 相关源码 数组 采用一段连续的存储单元来存储数据。对于指定下标的查找,时间复杂度为O(1);通过给定值进行查找,需要遍历数组,逐一比对给定关键字数组元素,时间复杂度为O(n),当然,对于有序数组,则可采用二分查找,插值查找,斐波那契查... 阅读详情

快速开始

HashMap相信大家在日常的开发中都用过,首先我们快速回忆下。

public class App {
   public static void main(String[] args) {
      //Map map = new HashMap<>();
      App map=new App();
      map.put("刘一", "刘一");
      map.put("陈二", "陈二");
      map.put("张三", "张三");
      map.put("李四", "李四");
      map.put("王五", "王五");
      map.put("springboot", "源码学院-只为培养BAT程序员而生");
      System.out.println(map.get("springboot"));
   }

hashmap在我们日常工作一般用的多的就是其put方法和get方法。

技术本质

现在我们已经对hashmap有一个大致的了解了,接下来我们要去了解其底层的原理,也就是本质。
在这里插入图片描述
很多朋友在面试的时候经常被问到hashmap底层实现原理?都说是数据+链表 ok!估计大家都会被了
但是真正知道底层如何存储的我相信不多,不急 我们来看下数组和链表的定义

数组

数组:采用一段连续的存储单元来存储数据。对于指定下标的查找,时间复杂度为O(1);对于一般的插入删除操作,
涉及到数组元素的移动,其平均复杂度也为O(n)

在这里插入图片描述
Java代码表示

   //数组:采用一段连续的存储单元来存储数据。
   //特点:指定下标O(1) 删除插入O(N) 数组:查询快 插入慢 ArrayList
   public static void main(String[] args) {
      Integer[] integers = new Integer[10];
      integers[0]=0;//王五
      integers[1]=1;
      integers[2]=2;
      integers[9]=9;

链表

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的
对于链表的新增,删除等操作(在找到指定操作位置后),仅需处理结点间的引用即可,时间复杂度为O(1),
而查找操作需要遍历链表逐一进行比对,复杂度为O(n)

在这里插入图片描述

public class Node {

   public Node  next;
   private Object data;

   public Node(Object data) {
      this.data = data;
   }
   //链表:链表是一种物理存储单元上非连续、非顺序的存储结构
   //特点:插入、删除时间复杂度O(1) 查找遍历时间复杂度0(N) 插入快 查找慢
   public static void main(String[] args) {
         Node node=new Node(15);
         node.next=new Node(1);
         node.next.next=new Node(9);
   }

哈希算法

哈希算法(也叫散列),就是把任意长度值(Key)通过散列算法变换成固定长度的key地址,通过这个地址进行访问的数据结构。
它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。
在这里插入图片描述

实现原理

刚才我们分析了hashmap由数组+链表构成,介绍了数组+链表的描述,接下来我们就把这两个数据结构整合在一起吧,在整合在一起
我们写一个伪put代码

 /***
    * 输出  key value hashcode 等 hash算法
    * @param key
    * @param value
    */
   public void put(String key, String value) {
      //hash函数
      System.out.printf("key:%s,hash值:%s,存储位置:%s\r\n", key, key.hashCode(), Math.abs(key.hashCode() % 15));
   }

运行代码如下

key:刘一,hash值:671464,存储位置:4
key:陈二,hash值:1212740,存储位置:5
key:张三,hash值:774889,存储位置:4
key:李四,hash值:842061,存储位置:6
key:王五,hash值:937065,存储位置:0
key:springboot,hash值:1362194047,存储位置:7

对应的图形存储结构就是:

在这里插入图片描述

实现

根据我们图形的演示,你能手写实现吗?

public interface Map<K,V> {
   public V put(K k,V v);
   public V get(K k);
   public int size();
   interface Entry<K,V>{
      public K getKey();
      public V getValue();
   }
}

具体实现:关注我的公众号,输入关键字hashmap即可下载源码。

在这里插入图片描述

深入理解HashMap原理()——手写HashMap 前言 前面一篇文章(深入理解HashMap原理()——HashMap源码解析(JDK 1.8))我们通过JDK 1.8的HashMap源码了解了HashMap的原理。俗话说:光说不练假把式。下面我们自己动手撸一个HashMap。本文基于JDK1.7 只写数组+链表结构。 思考 我们前面知道,HashMap的存储结构为散列表,解决哈希冲突是通过链表法解决的,结构如下: 那么我们也要来... 阅读详情

相关推荐

深入理解HashMap(三)resize方法解析

前言 上一篇讲了put方法,在put方法的最后,我们需要检查容量是否超过阈值,,如果越界需要进行扩容。resize方法就是对hashmap进行扩容。那么hashmap的扩容需要哪些步骤呢? 假如我是设计的作者,我会先创建一个更大容量的数组,然后遍历原table,重新计算所有的节点的hash值对应的下标,然后将节点转移到新table中。那么这其中存在这几个问题: 什么时候进行resize操作? 扩...

BodyCoding 6904

SpringBoot_day03之HashMap深入了解

1.hashmap的底层数据结构 1.8之前1.8的区别? 1、在JDK1.8之前HashMap由数组+链表 数据结构组成的。 2、在JDK1.8之后HashMap由数组+链表+红黑树 数据结构组成的。 2.hashmap存储元素的过程? put存值的方法,过程如下: 这写图片描述 ①.判断键值对数组table[i]是否为空或为null,否则执行resize()进行扩容; ②.根据键值key计算hash值得到插入的数组索引i,如果table[i]==null,直接新建 节点添加,转向⑥,如果ta

山有顶峰,湖有彼岸,漫漫长途中,万物皆有回转,当我们觉得余味苦涩,请你相信,一切终有回甘。 1154

架构师教你如何十分钟深入理解HashMap源码

十分钟就要深入理解HashMap源码,看完你能懂?我觉得得再多看一分钟,才能完全掌握! [外链图片转存失败(img-C72neM5a-1568723061512)(https://upload-images.jianshu.io/upload_images/16826084-eccd9643ad48ebf2.jpg?imageMogr2/auto-orient/strip%7CimageView...

Java_supermanNO1的博客 207

springboot使用HashMap的数据库

注解 @Data相当于类中有get与set方法 @NoArgsConstructor:相当于类中有无参构造器 @AllArgsConstructor:相当于类中有有参构造器 @Repository:使用@Repository注解可以确保DAO或者repositories提供异常转译,这个注解修饰的DAO或者repositories类会被ComponetScan发现并配置,同时也不需要为它们提供XML配置项。 @Autowired:自动导入依赖bean 1:Department表 @Data @NoArgsC

lllwky的博客 2291

hashMap底层原理(简单直白)

一,基础知识 1,数组,数组采用连续的存储单元存储数据,属于顺序存储结构,对于指定下标的查找,时间复杂度是O(1)。 2,链表:链表在内存空间上的存储是不连续的,属于链式存储结构。每个节点保存指向下一节点的指针。删除新增只需新建节点或改变指针,速度快。查询需遍历,比较慢慢。 3,hash表,通过对key值的hash计算,确定数据的存储位置。 4,Entry:hashMap的内部类,包含一个keyvalue键值对,一个hash值,以及指向下一个Entry的引用next 二,hashMap底层原理 1,ha

qq_40271222的博客 1317

springboot源码学习(一)- ConcurrentReferenceHashMap深度解读

一、前言 最近一直在阅读springboot的启动源码,它通过加载jar包中的META-INF/spring.factories文件,通过反射实例化其实现类,实现自动装配。其中有一个数据结构被设计来缓存从spring.factorys中读取的接口及其实现类,即:ConcurrentReferenceHashMap,拿出来给大家分享一下。 二、主要功能 支持高并发,基于分段锁实现,性能优于hashTable ConcurrentHashMap设计约束一致,但是支持keyvalue都为null 默认引用方

笑不语的博客 3799

Springboot初级:使用HashMap无实体类返回自定义字段给前端

HashMap恰好可以很好的应对这种使用场景,多组可以用List接收,而返回给前端的恰好是上图格式。需求:不增加新的实体类前提下,像数据查询并返回多组现实体类不包含的字段值给前端。

JamsMay的博客 974

深入理解 HashMap

什么是 HashMap? ​ HashMap 是基于哈希表的 Map 接口是实现的。此实现提供所有可选操作,并允许使用 null 做为值(key)键(value)。HashMap 不保证映射的顺序,特别是它不保证该顺序恒久不变。此实现假定哈希函数将元素适当的分布在各个桶之间,可作为基本操作(get put)提供稳定的性能。在jdk1.7中的HashMap是基于数组+链表实现的,在jdk1....

Woo_home的博客 3万+

深入理解HashMap

深入剖析了HashMap的实现原理源码

mazouri的博客 5346

强化基础,HashMap源码全角度详细解析

HashMap源码深度解析 一、重新认识HashMap 什么是HashMapHashMap底层基于散列(Hash)算法,采用hash表实现键值对集合,继承了AbstractMap,实现了Map接口。最早出现在jdk1.2,允许null键null值,null键的哈希值为0。需要注意的是HashMap不保证键值对顺序,同时非线程安全。 长啥样? 散列算法分为散列再探测拉链式,HashM...

静待花开 5531

HashMap源码分析(深入理解HashMap

1. HashMap总览 1.1 hashmap底层储存结构图解 底层结构其实就是数组+链表+红黑树 1.2 HashMap类定义 先来看看HashMap的定义: public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable {} 从中我们可以了解到: HashMap<K,V>:HashMap是以key-value形式存

PUPPET4的博客 5583

java实现hashmap附带源码

java实现hashmap附带源码

欢迎来到我的博客!这里是一个专注于计算机技术的分享平台,涵盖编程开发、算法研究、系统架构、软件工程等多个领域。无论你是初学者还是资深开发者,都能在这里找到有价值的内容。 1033

手撕源码系列:深入理解HashMap源码

手撕源码系列:深入理解HashMap源码 文章目录手撕源码系列:深入理解HashMap源码0.简介1.HashMap核心属性分析2.构造方法分析tableSizeFor()方法3.HashMap put方法与putVal方法分析put方法hash(Object key)putVal方法4.HashMap resize扩容方法分析resize()JDK 7 扩容的问题单线程resize多线程并发下的...

NayelyA的博客 644

深入理解 HashMap 关键部分源码

本文围绕 HashMap 展开,先简介其基于哈希表的 Map 接口实现、线程不安全特性,以及 JDK1.8 前后数组 + 链表、引入红黑树的结构差异与扩容树化规则;再从源码层面,解读常量、字段含义,分析 4 个构造函数逻辑,详解 hash 计算原理(右移 16 位及异或原因),并深入剖析 put、resize、get 核心方法的执行流程,展现 HashMap 的底层工作机制。

2302_80352818的博客 1378

java HashMap 源码分析(深度讲解)

java 集合篇章——HashMap源码分析(非常详细)。

CSDN / 稀土掘金/ B站 / GitHub: Cyan_RA9 2540

对JAVA的HashMap深入理解

定义两个int类型变量lc,hc,然后开始遍历这颗红黑树,我们来看一看遍历中的具体操作,首先定义了两个TreeNode变量e,赋值为b即这颗红黑树的根节点,然后定义了一个为初始化的TreeNode变量next,,然后遍历开始,首先赋值next为e的next节点,但我们查看TreeNode的定义发现并没有next的定义,我们可以知道这个是TreeNode的父类定义的,这给我们带来了一个重要的结论重新hash的过程中节点的hash值要么不变,要么加上一个bit位,画一个图来解释一下这个结论的重要意义,

weixin_61854715的博客 1050

【Java】从源码深入理解HashMapTreeMap

/ 降序排列// 遍历结果将按降序输出或者实现Comparableint age;@Override// 按年龄排序对比项红黑树AVL 树平衡标准黑高平衡(宽松)严格高度平衡(高度差 ≤ 1)插入/删除旋转次数最多 3 次可能 O(log n) 次查询效率O(log n),常数稍大略快(更严格平衡)适用场景频繁增删高频查询TreeMap 选择红黑树是因为它在增删查询之间取得了更好平衡。

sprinterz.blog.csdn.net 880
上一篇: Spring Boot入门(二):使用Profile实现多环境配置管理&如何获取配置文件值
下一篇: 深入理解JVM虚拟机(文末有视频讲解)
SpringBoot_
博客等级 码龄7年 445粉丝 96原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值