这一章节我们通过讨论装载因子与性能,再来介绍HashMap的工作原理。

1.什么是装载因子?他有什么作用?

以下的代码就是装载因子

 /**
* The load factor used when none specified in constructor.
*/
static final float DEFAULT_LOAD_FACTOR = 0.75f;

作用:就是控制什么时候map须要通过resize方法扩容。然后通过rehash方法把原有的元素拷贝到新的容器里面

2.装载因子与性能

/**
* Adds a new entry with the specified key, value and hash code to
* the specified bucket. It is the responsibility of this
* method to resize the table if appropriate.
*
* Subclass overrides this to alter the behavior of put method.
*/
void addEntry(int hash, K key, V value, int bucketIndex) {
Entry<K,V> e = table[bucketIndex];
table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
if (size++ >= threshold)
resize(2 * table.length);
}

我们看看上面的add方法。他主要用于put或者putall方法。把元素放到链表里面去的,可是他必须要检測map的大小,来确定是否须要resize。

我们再来看以下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, 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 >= initialCapacity
int capacity = 1;
while (capacity < initialCapacity)
capacity <<= 1; this.loadFactor = loadFactor;
threshold = (int)(capacity * loadFactor);
table = new Entry[capacity];
init();
}

观察上面两个函数,大家注意threshold 这个參数。在默认的构造函数里面threshold就是装载因子与初步容量所决定的。可是以下重写的hashmap构造函数。threshold 是由两个參数来决定的,而我们再回头看resize方法。他的运行与否,是由threshold 来决定的。因此得出结论:

是否resize,是由装载因子与初步容量来决定的。

我们再通过观察以下resize的源代码,得出一个结论,resize越多,性能越低。

resize的源代码:

void resize(int newCapacity) {
Entry[] oldTable = table;
int oldCapacity = oldTable.length;
if (oldCapacity == MAXIMUM_CAPACITY) {
threshold = Integer.MAX_VALUE;
return;
} Entry[] newTable = new Entry[newCapacity];
transfer(newTable);
table = newTable;
threshold = (int)(newCapacity * loadFactor);
}

由于resize须要把旧的元素拷贝到新的容器里面。

3.性能測试:

package com.ray.ch15;

import java.util.HashMap;

public class Test {
public static void main(String[] args) {
HashMap<Integer, String> map = new HashMap<Integer, String>();
long startTime = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
map.put(i, "a");
}
long endTime = System.currentTimeMillis();
System.out.println(endTime - startTime);
System.out.println("---------------");
HashMap<Integer, String> map2 = new HashMap<Integer, String>(100000, 1f);
startTime = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
map2.put(i, "a");
}
endTime = System.currentTimeMillis();
System.out.println(endTime - startTime);
}
}

输出:

47
---------------
15

上面的測试结果已经能够解释上面的结论。

总结:我们这一章节通过讨论装载因子与性能。再来介绍HashMap的工作原理。

这一章节就到这里,谢谢。

-----------------------------------

文件夹

从头认识java-15.7 Map(6)-介绍HashMap的工作原理-装载因子与性能的更多相关文章

  1. 从头认识java-15.7 Map(4)-介绍HashMap的工作原理-hash碰撞(常常作为面试题)

    这一章节我们来讨论一下hash碰撞. 1.什么是hash碰撞? 就是两个对象的key的hashcode是一样的,这个时候怎么get他的value呢? 答案是通过equals遍历table那个位置上面的 ...

  2. 从头认识java-15.7 Map(5)-介绍HashMap的工作原理-Key变了,能不能get出原来的value?(偶尔作为面试题)

    这一章节我们讨论一个比較特殊的情况Key变了,能不能get出原来的value? 答案是:有时能够,有时不能够 1.能够的情况: package com.ray.ch14; import java.ut ...

  3. 从头认识java-15.7 Map(3)-介绍HashMap的工作原理-get方法

    接着上一章节.我们来讨论一下get方法. 1.还是利用上一章节的图 下图引用自:http://www.admin10000.com/document/3322.html 我们简单说一下步骤.就是通过h ...

  4. 【转】Java学习---HashMap的工作原理

    [原文]https://www.toutiao.com/i6592560649652404744/ HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都 ...

  5. Java中的数据结构有哪些?HashMap的工作原理是什么?

    Java中常用数据结构 常用的数据结构有哈希表,线性表,链表,java.util包中有三个重要的接口:List,Set,Map常用来实现基本的数据结构 HashMap的工作原理 HashMap基于ha ...

  6. Java中的HashMap的工作原理是什么?

    问答题23 /120 Java中的HashMap的工作原理是什么? 参考答案 Java中的HashMap是以键值对(key-value)的形式存储元素的.HashMap需要一个hash函数,它使用ha ...

  7. Java HashMap的工作原理(转载)

    原文地址:http://www.importnew.com/10620.html 面试的时候经常会遇见诸如:"java中的HashMap是怎么工作的","HashMap的 ...

  8. [Java] SSH框架笔记_SSH三大框架的工作原理及流程

    Hibernate工作原理及为什么要用? 原理:1.通过Configuration().configure();读取并解析hibernate.cfg.xml配置文件2.由hibernate.cfg.x ...

  9. Java HashMap的工作原理

    面试的时候经常会遇见诸如:”java中的HashMap是怎么工作的”.”HashMap的get和put内部的工作原理”这样的问题. 本文将用一个简单的例子来解释下HashMap内部的工作原理. 首先我 ...

随机推荐

  1. 当网络中断的时候,JTA全局事务管理,究竟会不会回滚???

    前言:有人问了我一个问题,就是说在网络中断的时候,JTA的全局事务管理,会不会回滚?当时说会回滚,但没给对方说清楚理由,也不太认同我的观点.现在总结一下. 今天一天都在看文档(也查了一些博客和网站), ...

  2. ABP数据库的迁移

    添加表,一(Test)对多(Test1)关系 Test using Abp.Domain.Entities.Auditing; using System; using System.Collectio ...

  3. picPick使用研究

    WhiteBoard白板功能很强大. 可以直接在网页上进行圈画,然后截图. ImageEditor是一个很好用的画图功能,比windows画图的箭头好看.

  4. IB_DESIGNABLE 和 IBInspectable 的用法

    我们经常会在用一些自定义 UIView 来完成一些特殊的UI效果,但是怎么让我自定义的 UIView 在 Storyboard 中预览和修改一些自定义参数呢.这就需要用到两个吊吊的东西. IB_DES ...

  5. cf671B Robin Hood

    We all know the impressive story of Robin Hood. Robin Hood uses his archery skills and his wits to s ...

  6. spring中MessageSource的配置使用方法1

    Spring定义了访问国际化信息的MessageSource接口,并提供了几个易用的实现类.首先来了解一下该接口的几个重要方法:  String getMessage(String code, Ob ...

  7. hdu 1754 线段树(点修改)

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  8. 古代猪文 BZOJ 1951

    古代猪文 [问题描述] “在那山的那边海的那边有一群小肥猪.他们活泼又聪明,他们调皮又灵敏.他们自由自在生活在那绿色的大草坪,他们善良勇敢相互都关心……” ——选自猪王国民歌 很久很久以前,在山的那边 ...

  9. jquery插件的基本写法

    (function($){ var a={name:'2222',age:5555} var b={sex:'男',grade:5555} var c=$.extend({},a,b);//合并到新的 ...

  10. LeetCode OJ--Triangle **

    https://oj.leetcode.com/problems/triangle/ 一个三角形,类似于杨辉三角的形状,求从上到下最小的路径和,但走每一步都得是相邻的. 动态规划,从下到上一层层来. ...