码迷,mamicode.com
首页 > 编程语言 > 详细

【Java集合】——HashMap源码分析

时间:2019-12-22 18:27:21      阅读:91      评论:0      收藏:0      [点我收藏+]

标签:复杂   没有   shm   tran   static   hold   计算   缓存   city   

 

简介

        HashMap采用key/value存储结构,每个key对应唯一的value,查询和修改的速度都很快,能达到O(1)的平均时间复杂度。它是非线程安全的,且不保证元素存储的顺序;

 继承体系 

         技术图片

 

        分析:     

  • HashMap实现了Cloneable,可以被克隆。
  • HashMap实现了Serializable,可以被序列化。
  • HashMap继承自AbstractMap,实现了Map接口,具有Map的所有功能。

存储结构

      技术图片    

 在Java中,HashMap的实现采用了(数组 + 链表 + 红黑树)的复杂结构,数组的一个元素又称作桶。

在添加元素时,会根据hash值算出元素在数组中的位置,如果该位置没有元素,则直接把元素放置在此处,如果该位置有元素了,则把元素以链表的形式放置在链表的尾部。

当一个链表的元素个数达到一定的数量(且数组的长度达到一定的长度)后,则把链表转化为红黑树,从而提高效率。

数组的查询效率为O(1),链表的查询效率是O(k),红黑树的查询效率是O(log k),k为桶中的元素个数,所以当元素数量非常多的时候,转化为红黑树能极大地提高效率。

源码分析

/**
 * 默认的初始容量为16
 */
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;

/**
 * 最大的容量为2的30次方
 */
static final int MAXIMUM_CAPACITY = 1 << 30;

/**
 * 默认的装载因子
 */
static final float DEFAULT_LOAD_FACTOR = 0.75f;

/**
 * 当一个桶中的元素个数大于等于8时进行树化
 */
static final int TREEIFY_THRESHOLD = 8;

/**
 * 当一个桶中的元素个数小于等于6时把树转化为链表
 */
static final int UNTREEIFY_THRESHOLD = 6;

/**
 * 当桶的个数达到64的时候才进行树化
 */
static final int MIN_TREEIFY_CAPACITY = 64;

/**
 * 数组,又叫作桶(bucket)
 */
transient Node<K,V>[] table;

/**
 * 作为entrySet()的缓存
 */
transient Set<Map.Entry<K,V>> entrySet;

/**
 * 元素的数量
 */
transient int size;

/**
 * 修改次数,用于在迭代的时候执行快速失败策略
 */
transient int modCount;

/**
 * 当桶的使用数量达到多少时进行扩容,threshold = capacity * loadFactor
 */
int threshold;

/**
 * 装载因子
 */
final float loadFactor;

   (1)容量

   容量为数组的长度,亦即桶的个数,默认为16,最大为2的30次方,当容量达到64时才可以树化。

    (2)装载因子

   装载因子用来计算容量达到多少时才进行扩容,默认装载因子为0.75。

    (3)树化

   树化,当容量达到64且链表的长度达到8时进行树化,当链表的长度小于6时反树化。

   

【Java集合】——HashMap源码分析

标签:复杂   没有   shm   tran   static   hold   计算   缓存   city   

原文地址:https://www.cnblogs.com/2019wxw/p/12080287.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!