Map底层之HashMap原理浅析

HashMap是Java中常用的键值对存储结构,基于数组+链表实现。其工作原理包括通过key的hash值确定存储位置,当冲突发生时形成链表。在数据增多时,HashMap会进行扩容以保持较低的冲突率。与HashTable相比,HashMap非线程安全,但允许null键值,并在JDK1.8后引入了红黑树优化。理解HashMap的工作原理有助于提高使用效率。
摘要由CSDN通过智能技术生成

1.概述

Map<k,v="">是常见的键值对存储接口,Java中存储键值对的数据类型都实现了这个接口,表示映射表。其中有两个核心操作get(Object key)和put(K key, V value),分别用来获取键对应的值以及向映射表中插入键值对。

public interface Map<K,V> {
    ···
    V get(Object key);
    V put(K key, V value);
    ···
}

HashMap是Map的常见实现类,也是Java中使用最频繁的储存键值对的结构,这篇文章我们就来看一下它的基本原理。

 

2.HashMap的工作原理

Java中的数组在添加或者删除的时候,都会复制一个新数组,比较耗内存,但是数组遍历比较高效(寻址容易,插入和删除困难);然而,链表则是遍历比较慢,而添加和删除元素代价低(寻址困难,插入和删除容易)。HashMap则是巧妙的结合这两点——哈希表。

HashMap是一个用于存储Key-Value键值对的集合,每一个键值对也叫做Entry。这些键值对(Entry)分散存储在一个数组中,这个数组就是HashMap的主干。

从这张图可以看出来,HashMap是数组+链表实现的。在它的主干数组上,每一个元素存储的不仅是一个Entry对象,也是一个链表的头节点。每一个Entry通过Next指针指向它所在链表的下一个Entry节点。

 

2.1-put

一个HashMap默认的长度为16(数组长度)。当我们调用HashMap的put方法,向其中放入一个Entry(键值对)时,有这样一个问题要解决:这个Entry对象存储在HashMap中哪个位置?通过下面的算法来决定:

int hash = hash(key);
int i = indexFor(hash,table.length);

假如我们向HashMap中put(100,haozz)这个元素,那么首先需要计算100这个key的hash值,然后indexFor方法对该哈希值和HashMap数组的长度进行运算(实际上是与运算)。得到的值即是该元素存储在该HashMap中的下标值。

这样,我们就明确了新来的Entry对象存储在HashMap中的位置。那么新的问题又来了:如果我有两个Entry,他们通过上面的运算之后得到的下标相同,那该怎么办呢?这个时候就该链表登场了。我们之前说过,每一个Entry有一个Next属性指向下一个Entry。当新来的Entry对象(Entry-A)映射到的下标值为2,而且2位置上已经有对象(Entry-B)的时候,它只需要插入到对应的链表即可。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值