初步了解HashMap底层数据结构

HashMap原理与使用(初步认识)

本文主要讲述HashMap的一些简单原理,如果讲的不好,可以说出来,让我改正本文。

1. HashMap的数据结构

说到HashMap的数据结构,就需要说到数据结构中的数组和单链表结构,因为HashMap的底层就是数组和链表,不过这是JDK1.7版本的,1.8版本后加入了红黑树。下面先介绍一些这些数据结构。

数组

数组存储区间是连续的,占用内存严重,故空间复杂的很大。但数组的二分查找时间复杂度小,为O(1);数组查找时间复杂度O(1)是指,通过下标访问这个下标的数据,而二分查找时间是O(long2n),还有一个很重要的前提条件这个数组是要一个有序数组。数组的特点是:寻址容易,插入和删除困难

在这里插入图片描述

单链表

链表存储区间离散,占用内存比较宽松,故空间复杂度很小,但时间复杂度很大,达O(N)。链表的特点是:寻址困难,插入和删除容易

在这里插入图片描述

哈希表

相比上述几种数据结构,在哈希表中进行添加,删除,查找等操作,性能十分之高,不考虑哈希冲突的情况下(后面会探讨下哈希冲突的情况),仅需一次定位即可完成,时间复杂度为O(1),接下来我们就来看看哈希表是如何实现达到惊艳的常数阶O(1)的。

我们知道,数据结构的物理存储结构只有两种:顺序存储结构和链式存储结构(像栈,队列,树,图等是从逻辑结构去抽象的,映射到内存中,也这两种物理组织形式),而在上面我们提到过,在数组中根据下标查找某个元素,一次定位就可以达到,哈希表利用了这种特性,哈希表的主干就是数组,HashMap的就是利用了哈希表的这种构造思想。

比如我们要新增或查找某个元素,我们通过把当前元素的关键字 通过某个函数映射到数组中的某个位置,通过数组下标一次定位就可完成操作。
  
这个函数可以简单描述为:存储位置 = f(关键字) ,这个函数f一般称为哈希函数,这个函数的设计好坏会直接影响到哈希表的优劣。

红黑树

红黑树(Red Black Tree) 是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组。在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。它的最坏情况运行时间也是非常良好的,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除,这里的n 是树中元素的数目

红黑树有几种特性:

  • 每个节点只能是红色或者黑色。
  • 根节点必须是黑色。
  • 红色的节点,它的叶节点只能是黑色。
  • 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。
    在这里插入图片描述

jdk1.7版本的HashMap数据结构图(数组+单链表)

jdk1.7版本的HashMap可以看作是Entry数组和链表结合组成的复合结构,数组中的每一个储存块都存储有一个或多个Entry对象,每个Entry对象包含三部分key(键)、value(值),next(指向下一个Entry),通过哈希值决定了Entry对象在这个数组的寻址;哈希值相同的Entry对象(键值对),则以链表形式存储

在这里插入图片描述

jdk1.8版本的HashMap数据结构图(数组+单链表+红黑树)

与jdk1.7相比,jdk1.8加入了红黑树。为什么加入红黑树?这是因为红黑树虽然本质上是一棵二叉查找树,它在二叉查找树的基础上增加了着色和相关的性质使得红黑树相对平衡,从而保证了红黑树的查找、插入、删除的时间复杂度最坏为O(log n)。加快检索速率。

在jdk1.8版本的HashMap中

当单链表中数据的临界值数量如果达到8以上,数组的size小于64,就进行resize扩展

static  final  int TREEIFY_THRESHOLD = 8;//链表临界值

如果数据的临界值,如果大于8,且数组的size是否大于64,则把对应链表进行转化为红黑树

static  final  int MIN_TREEIFY_CAPACITY = 64//数组临界值

在这里插入图片描述

参考文章:https://blog.csdn.net/woshimaxiao1/article/details/83661464

2 深入了解HashMap的源码

如果先深入了解HasMap的源码下面这篇文章说的很不错,想深入的可以看看

史上最详细的 JDK 1.8 HashMap 源码解析

3 Hashmap的结构,1.7和1.8有哪些区别

深入了解:Hashmap的结构,1.7和1.8有哪些区别

4 常用方法

1. 构造方法摘要

  • HashMap():构造一个具有默认初始容量 (16) 和默认加载因子 (0.75) 的空 HashMap。
  • HashMap(int initialCapacity):构造一个带指定初始容量和默认加载因子 (0.75) 的空 HashMap。
  • HashMap(int initialCapacity, float loadFactor):构造一个带指定初始容量和加载因子的空 HashMap。
  • HashMap(Map<? extends K,? extends V> m):构造一个映射关系与指定 Map 相同的 HashMap。

2.方法摘要

  • void clear():从此映射中移除所有映射关系。
  • Object clone():返回此 HashMap实例的浅表复制:并不克隆键和值本身。
  • boolean containsKey(Object key):如果此映射包含对于指定的键的映射关系,则返回 true。
  • boolean containsValue(Object value): 如果此映射将一个或多个键映射到指定值,则返回 true。
  • Set<Map.Entry<K,V>> entrySet():返回此映射所包含的映射关系的 collection 视图。
  • V get(Object key):返回指定键在此标识哈希映射中所映射的值,如果对于此键来说,映射不包含任何映射关系,则返回 null。
  • boolean isEmpty():如果此映射不包含键-值映射关系,则返回 true。 Set keySet():返回此映射中所包含的键的set 视图。
  • V put(K key, V value): 在此映射中关联指定值与指定键。
  • void putAll(Map<?extends K,? extends V>m):将指定映射的所有映射关系复制到此映射中,这些映射关系将替换此映射目前针对指定映射的所有键的所有映射关系。
  • V remove(Object key): 如果此映射中存在该键的映射关系,则将其删除。
  • int size():返回此映射中的键-值映射关系数。
  • Collection values():返回此映射所包含的值的collection 视图。
  • getOrDefault(): 方法获取指定 key 对应对 value,如果找不到 key ,则返回设置的默认值。

参考文章:https://blog.csdn.net/qq_36254699/article/details/100123946

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值