HashMap底层原理

HashMap是Java中基于哈希表的数据结构,采用数组+链表/红黑树实现。在JDK1.8之前,它存在哈希碰撞导致效率降低的问题。为了解决这一问题,JDK1.8引入了红黑树,当链表长度超过8时转换为红黑树,降低查询时间复杂度。默认加载因子0.75是为了在容量和性能间取得平衡。HashMap的put和get操作涉及到哈希计算和扩容机制,resize方法在元素达到特定阈值时执行扩容。
摘要由CSDN通过智能技术生成

1.HashMap的概念

HashMap基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)HashMap不保证映射的顺序,特别是它不保证该顺序恒久不变。
在这里插入图片描述

2.底层数据结构

HashMap底层采用哈希表结构(数组+链表、JDK1.8后为数组+链表+红黑树)实现,结合了数组和链表的优点:

数组优点: 通过数组下标可以快速实现对数组元素的访问,效率极高;

链表优点: 插入或删除数据不需要移动元素,只需修改节点引用,效率极高。

HashMap图示如下:
在这里插入图片描述

HashMap内部使用数组存储数据,数组中的每个元素类型为Node<K,V>:

//Node包含了四个字段:hash、key、value、next,其中next表示链表的下一个节点。
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 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;
  }
}

2.JDK1.8之前存在的问题?

JDK1.8之前,HashMap底层实现用的是数组+链表。(JDK1.8以后用数组+链表+红黑树)。

HashMap通过hash方法计算key的哈希码,然后通过(n-1)&hash 公式(n为数组长度,初始化数组默认长度为16),得到key在数组中存放的下标。

当两个key在数组中存在的下标一致时(哈希冲突,哈希碰撞),数据将以链表的方式存储。

在链表中查找数据必须从第一个元素开始一层一层往下找,直到找到为止,时间复杂度为O(N),所以当链表长度越来越长时,HashMap的效率越来越低。

哈希码如何计算?添加链接描述


如何解决?
加入红黑树
当链表中的元素超过8个(TREEIFY_THRESHOLD)并且数组长度大于64(MIN_TREEIFY_CAPACITY)时,会将链表转换为红黑树,转换后数据查询时间复杂度从O(N)变为O(logN)。

红黑树的节点使用TreeNode表示:

static final class TreeNode<K,V> extends LinkedHashMap.Entry<K,V> {
    
   TreeNode<K,V> parent;  // red-black tree links    
   TreeNode<K,V> left;    
   TreeNode<K,V> right;    
   TreeNode<K,V> prev;    // needed to unlink next upon deletion    
   boolean red;    
   TreeNode(int hash, K key, V val, Node<K,V> next) 
  • 2
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值