HashMap 的性能因子

1. 容量:表示桶位的数量。

2. 初始容量: 表在创建是所拥有的桶位数。

  •   如果你知道将要在HashMap存储多少项,创建一个初始容量合适的HashMap将可以避免自动再散列的开销
    /**
* The default initial capacity - MUST be a power of two.
*/
static final int DEFAULT_INITIAL_CAPACITY = 1
3. 尺寸: 表中当前存储的项数。 4. 负载因子:尺寸/容量。 负载因子小的表冲突的可能性小,插入和查找的速度也相对较快(但会减慢使用迭代器进行遍历的过程)。HashMap和HashSet都具有允许你指定负载因子的构造器,表示当负载情况达到负载因子的水平时,容器将自动增加容量。实现方法是使容量加倍,并将现有对象分配到新的桶位集中。
    /**
* The load factor used when none specified in constructor.
*/
static final float DEFAULT_LOAD_FACTOR = 0.75f;

 

HashMap构造器

HashMap(int initialCapacity, float loadFactor);
 initialCapacity为初始容量, loadFactor为负载因子
       /**
     * Constructs an empty <tt>HashMap</tt> with the specified initial
     * capacity and load factor.
     *
     * @param  initialCapacity the initial capacity
     * @param  loadFactor      the load factor
     * @throws IllegalArgumentException if the initial capacity is negative
     *         or the load factor is nonpositive
     */
    public HashMap(int initialCapacity, float loadFactor) {
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal initial capacity: " +
                    initialCapacity);
        if (initialCapacity > MAXIMUM_CAPACITY)  // MAXIMUM_CAPACITY为最大容量
            initialCapacity = MAXIMUM_CAPACITY;
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal load factor: " +
                    loadFactor);
        this.loadFactor = loadFactor;         this.threshold = tableSizeFor(initialCapacity); // tableSizeFor(initialCapacity) 会返回x(x表示2的整数次幂)
//threshold是一个阙值,它等于 负载因子*尺寸, 当然这里暂时等于容量
//当调用resize函数后才开始真正分配空间(槽位),这时才赋给threshold真正意义上的值
    }

 

来看看tableSizeFor的实现(个人绝对想不到这么高大上的方法)

    /**
* Returns a power of two size for the given target capacity.
*/
static final int tableSizeFor(int cap) {
int n = cap - 1; //这里是因为考虑到cap为2的整数次幂的情况 //1. 假设此时n的二进制最高位1在第i位(最低位为第0位) n |= n >>> 1; //2. 此时n的二进制第i, i-1位都为1 n |= n >>> 2; //3. 此时n的二进制第i, i-1, i-2, i-3位都为1 n |= n >>> 4; //4. 此时n的二进制第i, i-1, i-2, i-3, i-4, i-5, i-6, i-7位都为1(当然,严谨点应该再假设i>7) n |= n >>> 8;
//5.---------
n |= n >>> 16;
//6.---------
return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}

 

添加元素

 

    public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
} /**
* Implements Map.put and related methods
*
* @param hash hash for key
* @param key the key
* @param value the value to put
* @param onlyIfAbsent if true, don't change existing value
* @param evict if false, the table is in creation mode.
* @return previous value, or null if none
*/
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
Node<K,V>[] tab; Node<K,V> p; int n, i;
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
if ((p = tab[i = (n - 1) & hash]) == null) // 判断是否发生冲突
tab[i] = newNode(hash, key, value, null); // 没反生冲突,直接放入第i个槽位
else {
//执行到这里,表示发生冲突了
Node<K,V> e; K k;
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p; //如果key相等,直接把新value覆盖原value
else if (p instanceof TreeNode) //判断当前解决冲突所用的数据结构是不是TreeNode(红黑树)
//这是当冲突过多(某个槽位冲突数超过TREEIFY_THRESHOLD=8)时,
//HashMap的优化方式
e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
else {
// 执行到这里说明当前解决冲突所用结构是链表
for (int binCount = 0; ; ++binCount) {
if ((e = p.next) == null) {
p.next = newNode(hash, key, value, null);
if (binCount >= TREEIFY_THRESHOLD - 1) // 冲突数超过TREEIFY_THRESHOLD
// 用红黑树代替链表
treeifyBin(tab, hash);
break;
}
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;
}
}
if (e != null) { //如果map存在与新key相等的key,直接把新value覆盖原value
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
e.value = value;
afterNodeAccess(e);
return oldValue;
}
}
++modCount;
if (++size > threshold) //判断当前尺寸是否大于阙值(即负载是否大于负载因子)
resize();
afterNodeInsertion(evict);
return null;
}

 

博客园(FOREVER_ENJOY):http://www.cnblogs.com/zyx1314/p/5359434.html

本文版权归作者所有;欢迎转载!请注明文章作者和原文连接

java HashMap的更多相关文章

  1. [翻译]Java HashMap工作原理

    大部分Java开发者都在使用Map,特别是HashMap.HashMap是一种简单但强大的方式去存储和获取数据.但有多少开发者知道HashMap内部如何工作呢?几天前,我阅读了java.util.Ha ...

  2. Java学习笔记(二二)——Java HashMap

    [前面的话] 早上起来好瞌睡哈,最近要注意一样作息状态.       HashMap好好学习一下. [定义] Hashmap:是一个散列表,它存储的内容是键值对(key——value)映射.允许nul ...

  3. java集合框架之java HashMap代码解析

     java集合框架之java HashMap代码解析 文章Java集合框架综述后,具体集合类的代码,首先以既熟悉又陌生的HashMap开始. 源自http://www.codeceo.com/arti ...

  4. HashMap的原理与实 无锁队列的实现Java HashMap的死循环 red black tree

    http://www.cnblogs.com/fornever/archive/2011/12/02/2270692.html https://zh.wikipedia.org/wiki/%E7%BA ...

  5. 【转】Java HashMap工作原理(好文章)

    大部分Java开发者都在使用Map,特别是HashMap.HashMap是一种简单但强大的方式去存储和获取数据.但有多少开发者知道HashMap内部如何工作呢?几天前,我阅读了java.util.Ha ...

  6. 【转】Java HashMap 源码解析(好文章)

    ­ .fluid-width-video-wrapper { width: 100%; position: relative; padding: 0; } .fluid-width-video-wra ...

  7. 转:Java HashMap实现详解

    Java HashMap实现详解 转:http://beyond99.blog.51cto.com/1469451/429789 1.    HashMap概述:    HashMap是基于哈希表的M ...

  8. 自学Java HashMap源码

    自学Java HashMap源码 参考:http://zhangshixi.iteye.com/blog/672697 HashMap概述 HashMap是基于哈希表的Map接口的非同步实现.此实现提 ...

  9. Java HashMap工作原理及实现

    Java HashMap工作原理及实现 2016/03/20 | 分类: 基础技术 | 0 条评论 | 标签: HASHMAP 分享到:3 原文出处: Yikun 1. 概述 从本文你可以学习到: 什 ...

  10. 【转】Java HashMap的死循环

    问题的症状 从前我们的Java代码因为一些原因使用了HashMap这个东西,但是当时的程序是单线程的,一切都没有问题.后来,我们的程序性能有问题,所以需要变成多线程的,于是,变成多线程后到了线上,发现 ...

随机推荐

  1. tomcat源码剖析系列

    一个简单的web服务器 一个简单的servlet容器 连接器 创建httpRequest 创建HttpResponse 容器 生命周期 日志记录器 载入器 Session管理 关闭钩子 启动tomca ...

  2. Windows下程序打包发布时的小技巧

    一.背景 Windows下开发的应用程序在发布时,需要将其依赖的一些动态链接库一起打进安装包里面去.这个时候,快速确定这个程序到底依赖哪些动态链接库变得非常重要.很久以前写过一篇关于Qt程序安装包制作 ...

  3. JS设置CSS样式的几种方式

    用JS来动态设置CSS样式,常见的有以下几种 1. 直接设置style的属性  某些情况用这个设置 !important值无效 如果属性有'-'号,就写成驼峰的形式(如textAlign)  如果想保 ...

  4. WebView JS与RN进行通讯

    RN0.37终于官方增加了WebView与React Native的通讯,之前一真使用的是第三方控件React-Native-WebView-Bridge,但不是知道怎么回事这个第三方控件喊了很长时间 ...

  5. MVC学习系列8--分页和排序

    分页和排序,应该是软件开发中,需要必知必会的技能了,对于分页,网上很多教程,当然,别人终究是别人的,只有自己理解,会了,并且吸收之后,再用自己的语言,传授出来,这才是硬道理.好了,废话说多了.现在我们 ...

  6. 悟透JavaScript

    要理解JavaScript,你得首先放下对象和类的概念,回到数据和代码的本原.前面说过,编程世界只有数据和代码两种基本元素,而这两种元素又有着纠缠不清的关系.JavaScript就是把数据和代码都简化 ...

  7. Mysql在大型网站的应用架构演变

    原创文章,转载请注明: 转载自http://www.cnblogs.com/Creator/本文链接地址: Mysql在大型网站的应用架构演变 本文已经被多处转载,包括CSDN推荐以及码农周刊等等,阅 ...

  8. No.025:Reverse Nodes in k-Group

    问题: Given a linked list, reverse the nodes of a linked list k at a time and return its modified list ...

  9. 在多行列表中id同名的<a>标签点击事件处理方法

    Struts2标签 问题描述:最近项目中在使用struts迭代标签动态生成列表的过程中,由于每一行li元素中包含<a>超链接,如下图 一开始超链接是这样的<a href=“#” id ...

  10. Apache Lucene(全文检索引擎)—创建索引

    目录 返回目录:http://www.cnblogs.com/hanyinglong/p/5464604.html 本项目Demo已上传GitHub,欢迎大家fork下载学习:https://gith ...