一、结构

HashMap的结构由数组和链表组成,可以说是一个链表类型的数组:

快速定位方式:key值得hash变换作为数组索引快速找到对应数组块,之后通过hash值对比从链表中查找到匹配项。

hash函数:

  1. hash()

key的hash值是实际是key的hashCode值的低16位与高16位异或结果。之所以这样是为了减少数组定位时发生哈希碰撞。

数组下标是这样确定的:

  1. i =(n-1)& hash //n=tab.length(),hash = hash(key)

从数组下标确定算法可以看出,实际参与运算的基本都是hash的低位,这样发生哈希冲突的可能性就比较高,所以hash函数中才会用hashcode值高低位取异或;

二、默认参数

  1. 1 /**
  2. 2 * The default initial capacity - MUST be a power of two.
  3. 3 */
  4. 4 static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
  5. 5
  6. 6 /**
  7. 7 * The maximum capacity, used if a higher value is implicitly specified
  8. 8 * by either of the constructors with arguments.
  9. 9 * MUST be a power of two <= 1<<30.
  10. 10 */
  11. 11 static final int MAXIMUM_CAPACITY = 1 << 30;
  12. 12
  13. 13 /**
  14. 14 * The load factor used when none specified in constructor.
  15. 15 */
  16. 16 static final float DEFAULT_LOAD_FACTOR = 0.75f;

规定HashMap容量总为2的幂次方,最小16,最大2的30次方;

DEFAULT_LOAD_FACTOR 默认的负载因子,参与通过无参构造的HashMap初始容量计算。

三、属性

  1. 1 transient Node<K,V>[] table;
  2. 2 transient Set<Map.Entry<K,V>> entrySet;
  3. 3 transient int size;
  4. 4 //容量阈值
  5. 5 int threshold;
  6. 6 //负载因子
  7. 7 final float loadFactor;

当通过无参构造函数初始化时,loadFactor = DEFAULT_LOAD_FACTOR。实际上通过无参构造HashMap时,初始容量为 = DEFAULT_INITIAL_CAPACITY * loadFactor(见方法rsize())。

四、构造函数

hashMap有4个构造函数;

一个无参构造,初始容量和负载因子都取默认值;

一个通过已有Map构造;

两个自定义容量构造;

jdk1.8的构造函数并没有初始化table,table初始化放在了第一次put中。

  1. 1 public HashMap(int initialCapacity, float loadFactor) {
  2. 2 if (initialCapacity < 0)
  3. 3 throw new IllegalArgumentException("Illegal initial capacity: " +
  4. 4 initialCapacity);
  5. 5 if (initialCapacity > MAXIMUM_CAPACITY)
  6. 6 initialCapacity = MAXIMUM_CAPACITY;
  7. 7 if (loadFactor <= 0 || Float.isNaN(loadFactor))
  8. 8 throw new IllegalArgumentException("Illegal load factor: " +
  9. 9 loadFactor);
  10. 10 this.loadFactor = loadFactor;
  11. 11 this.threshold = tableSizeFor(initialCapacity);
  12. 12 }

除了无参构造,都应用到一个方法tableSizeFor();

tableSizeFor

此算法计算出大于等于入参的最小2的幂次方,由于规定map容量必须为2的幂次方,所以经由此方法得出自定义的最佳容量。

HashMap源码分析笔记(一)的更多相关文章

  1. 基于jdk1.8的HashMap源码学习笔记

    作为一种最为常用的容器,同时也是效率比较高的容器,HashMap当之无愧.所以自己这次jdk源码学习,就从HashMap开始吧,当然水平有限,有不正确的地方,欢迎指正,促进共同学习进步,就是喜欢程序员 ...

  2. HashMap源码阅读笔记

    HashMap源码阅读笔记 本文在此博客的内容上进行了部分修改,旨在加深笔者对HashMap的理解,暂不讨论红黑树相关逻辑 概述   HashMap作为经常使用到的类,大多时候都是只知道大概原理,比如 ...

  3. 【JAVA集合】HashMap源码分析(转载)

    原文出处:http://www.cnblogs.com/chenpi/p/5280304.html 以下内容基于jdk1.7.0_79源码: 什么是HashMap 基于哈希表的一个Map接口实现,存储 ...

  4. zeromq源码分析笔记之线程间收发命令(2)

    在zeromq源码分析笔记之架构说到了zmq的整体架构,可以看到线程间通信包括两类,一类是用于收发命令,告知对象该调用什么方法去做什么事情,命令的结构由command_t结构体确定:另一类是socke ...

  5. Java中HashMap源码分析

    一.HashMap概述 HashMap基于哈希表的Map接口的实现.此实现提供所有可选的映射操作,并允许使用null值和null键.(除了不同步和允许使用null之外,HashMap类与Hashtab ...

  6. JDK1.8 HashMap源码分析

      一.HashMap概述 在JDK1.8之前,HashMap采用数组+链表实现,即使用链表处理冲突,同一hash值的节点都存储在一个链表里.但是当位于一个桶中的元素较多,即hash值相等的元素较多时 ...

  7. HashMap源码分析和应用实例的介绍

    1.HashMap介绍 HashMap 是一个散列表,它存储的内容是键值对(key-value)映射.HashMap 继承于AbstractMap,实现了Map.Cloneable.java.io.S ...

  8. 【Java】HashMap源码分析——常用方法详解

    上一篇介绍了HashMap的基本概念,这一篇着重介绍HasHMap中的一些常用方法:put()get()**resize()** 首先介绍resize()这个方法,在我看来这是HashMap中一个非常 ...

  9. 【Java】HashMap源码分析——基本概念

    在JDK1.8后,对HashMap源码进行了更改,引入了红黑树.在这之前,HashMap实际上就是就是数组+链表的结构,由于HashMap是一张哈希表,其会产生哈希冲突,为了解决哈希冲突,HashMa ...

随机推荐

  1. 2.3-STP生成树

    2.3-STP生成树     单点失效(signle point of failure)及其解决方法:     当两个Segement之间只有一条物理连接时就有可能出现单点失效→ 单方面的故障导致全网 ...

  2. vue组件的一个总结

    用vue进行开发到目前为止也有将近一年的时间了,在项目技术选型的时候隔壁组选 react的时候我们坚持使用vue作为前端的开发框架.虽然两者思想上的差异不大,但是vue的语法在代码的可读性以及后期的维 ...

  3. Spring发送邮件_javax.mail.AuthenticationFailedException异常已解决

    在Spring项目中须要增加监控功能.监控过程中发现异常时.须要邮件报警.最初选择用javamail发送,代码量比較大(相对于spring发送).终于选择Spring邮件发送~ 以下贴一下实现的代码以 ...

  4. Android系统Recovery工作原理之使用update.zip升级过程分析(八)---解析并执行升级脚本updater-script【转】

    本文转载自:http://blog.csdn.net/mu0206mu/article/details/7465551  Android系统Recovery工作原理之使用update.zip升级过程分 ...

  5. MVC + Redis

    net MVC + Redis(hash入库+log4net集成) https://www.cnblogs.com/hoyu/p/9063675.html 博客四元素 既然要写一个博客类的网站,那就应 ...

  6. 试用php的ping命令

    使用PHP自动PING IP,校检网络连接是否正常! <?php $server = 'ping kalvin.cn -n 1'; $last_line = exec($server, $arr ...

  7. Grafana+Zabbix+Prometheus 监控系统

    环境说明 软件 版本 操作系统 IP地址 Grafana 5.4.3-1 Centos7.5 192.168.18.231 Prometheus 2.6.1 Centos7.5 192.168.18. ...

  8. Run as ant build每次都执行两次-问题解决

    在Eclipse里面,运行ant,整个测试流程总是执行两遍,其几天试了下在DOS命令行直接调用ant, 结果发现只执行了一次,并且内存消耗好像也没那么大了,估计是eclipse自己的问题.问题解决了, ...

  9. python3爬取豆瓣排名前250电影信息

    #!/usr/bin/env python # -*- coding: utf-8 -*- # @File : doubanmovie.py # @Author: Anthony.waa # @Dat ...

  10. 网络开发之使用Web Service和使用WCF服务

    判断是否有可用网络连接可以通过NetworkInterface类中的GetIsNetworkAvailable来实现: bool networkIsAvailable = networkInterfa ...