当前位置:   article > 正文

HashMap底层原理_hashmap底层实现原理

hashmap底层实现原理

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;
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

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<
  • 1
  • 2
  • 3
  • 4
  • 5
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/227341
推荐阅读
相关标签
  

闽ICP备14008679号