精英联盟总队|面试官:说一下HashMap原理,为什么会产生死循环
Map 这样的 Key Value 在软件开发中是非常经典的结构 , 常用于在内存中存放数据 。 众所周知 HashMap 底层是基于 数组 + 链表 组成的 , 不过在 JDK1.7 和 1.8 中具体实现稍有不同 。
今天我们只讲解JDK1.7版本的HashMap 。
1、HashMap的数据结构图是一个数组+链表结构
2、HashMap成员变量
/** * The default initial capacity - MUST be a power of two. */static final int DEFAULT_INITIAL_CAPACITY = 16;/** * The maximum capacity, used if a higher value is implicitly specified * by either of the constructors with arguments. * MUST be a power of two <= 1<<30. */static final int MAXIMUM_CAPACITY = 1 << 30;/** * The load factor used when none specified in constructor. */static final float DEFAULT_LOAD_FACTOR = 0.75f;/** * The table, resized as necessary. Length MUST Always be a power of two. */transient Entry这是 HashMap 中比较核心的几个成员变量;看看分别是什么意思?
① DEFAULT_INITIAL_CAPACITY :初始化桶大小(16) , 因为底层是数组 , 所以这是数组默认的大小 。
② MAXIMUM_CAPACITY :桶最大值 。
③ DEFAULT_LOAD_FACTOR :默认的负载因子(0.75)
④ table:真正存放数据的数组 。
⑤ size:map中存放的键值对的数量 。
⑥ threshold:resize扩容时的阈值 。
⑦ loadFactor:负载因子 , 可在初始化时显式指定 。
HashMap 的构造函数可以指定参数也可以无参:
public HashMap() {this.loadFactor = DEFAULT_LOAD_FACTOR;threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);table = new Entry[DEFAULT_INITIAL_CAPACITY];init();}public HashMap(int initialCapacity) {this(initialCapacity, DEFAULT_LOAD_FACTOR);}public HashMap(int initialCapacity, float loadFactor) {if (initialCapacity < 0)throw new IllegalArgumentException("Illegal initial capacity: " +initialCapacity);if (initialCapacity > MAXIMUM_CAPACITY)initialCapacity = MAXIMUM_CAPACITY;if (loadFactor <= 0 || Float.isNaN(loadFactor))throw new IllegalArgumentException("Illegal load factor: " +loadFactor);// Find a power of 2 >= initialCapacityint capacity = 1;while (capacity < initialCapacity)capacity <<= 1;this.loadFactor = loadFactor;threshold = (int)Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1);table = new Entry[capacity];useAltHashing = sun.misc.VM.isBooted()init();}默认容量为 16 , 负载因子为 0.75 。 Map 在使用过程中不断的往里面存放数据 , 当数量达到了 16 * 0.75 = 12 就需要将当前 16 的容量进行扩容 , 而扩容这个过程涉及到 rehash、复制数据等操作 , 所以非常消耗性能 。
因此通常建议能提前预估 HashMap 的大小最好 , 尽量的减少扩容带来的性能损耗 。
3、Entry类根据代码可以看到真正存放数据的是:transient Entry
推荐阅读
- 骚狐君|他的存在对鲨鱼产生了威胁,和平精英人气榜公布!牧童稳坐第一
- nba|NBA太疯狂!2组1-1,1组2-2,联盟第1最悲惨!黑马逆袭,成赢家
- 大华联盟|朱元璋下令锯开棺材 6个大字朱元璋脸色大变,刘伯温下葬后
- 英雄联盟|余霜分手后开启奔放模式,一天连晒N组自拍,网友直呼太美了!
- 卡玛拉|《复仇者联盟》:不只是游戏,更是一部优秀的电影
- 和平精英|??“吃鸡”体验服已无更新,暗夜危机2.0,或将被1款新游戏代替!
- 英雄联盟|LOL九周年奖励发放,玩家开始“比惨大会”,你是欧皇还是非酋?
- 悠游侠|漫威复仇者联盟装备怎么升级 装备等级提升方法介绍
- 和平精英|和平精英三大一哥宣告诞生:王小歪排名第一,日赚1W3!
- 英雄联盟|LEC解说强行给帽皇树敌:不管你们怎么说,Caps都会打爆左手!
