这一章节我们通过讨论装载因子与性能,再来介绍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. Z-Score数据标准化处理(python代码)

    #/usr/bin/python def Z_Score(data): lenth = len(data) total = sum(data) ave = float(total)/lenth tem ...

  2. 【Luogu】P3786萃香抱西瓜(状压DP)

    题目链接 水题,数据范围提示得太明显了吧,不用动脑子都能知道是状压. 不过还是有坑(当然更可能是我脑子有坑) f[i][j][k][l]表示当前是第i秒,萃香在(j,k),已经抱到的西瓜状态是l的最少 ...

  3. Eclipse + Apache Axis2 发布RESTful WebService(三)第一个程序Hello Axis2 !(未成功)

    此路不通 Axis2发布SOAP WebService非常简单,建一个Dynamic Web Project,然后为它建一个Axis的Web Service(Tomcat7+JDK),就会生成Clas ...

  4. Windows cmd 生成目录结构 dir /b,tree /f,xcopy

    >dir *.sh *.ksh *.java /s/b > list.txt >tree /f > list.txt >xcopy C:\folder\from_fold ...

  5. javaweb学习总结(九)—— 通过Servlet生成验证码图片(转)

    (每天都会更新至少一篇以上,有兴趣的可以关注)转载自孤傲苍狼 一.BufferedImage类介绍 生成验证码图片主要用到了一个BufferedImage类,如下:

  6. 【POJ2104】K-th Number(主席树)

    题意:有n个数组成的序列,要求维护数据结构支持在线的下列两种操作: 1:单点修改,将第x个数修改成y 2:区间查询,询问从第x个数到第y个之间第K大的数 n<=100000,a[i]<=1 ...

  7. uniSWF使用注意事项

    美术方面,也就是使用FLASH这里的用户,请注意以下几点, 1.把相同的图案做成元件: 2.凡是补间产生的动画物体,也要做成元件: 以上便可以节省大量的空间,因为当迩把图案做成元件的话,UNISWF导 ...

  8. Django的日志中关闭elasticsearch模块的日志

    今天用python的日志模块,为Django项目配置了日志,运行的时候发现日志在疯狂的涨,检查后发现竟然是elasticsearch的日志,但是我没有打这个日志啊,根据日志提供的文件位置,我在elas ...

  9. Button Style Status

    <Window x:Class="Dxsl.WPF.APP.Views.StyleTest2" xmlns="http://schemas.microsoft.co ...

  10. 编译 Android 版本的 Opus 音频编解码库的方法

    Opus 音频编解码库是 Speex 音频编解码库的下一代版本,从编解码性能以及质量上来讲都有了长足的进步.Opus 的编译非常简单,但是官方并未给出详细的 Android 版本编译指南,查找了大量资 ...