概述

 

HashMap是Map接口的一个哈希表的实现,内部是一个数组表示的。数组中的元素叫做一个Node,一个Node可以一个是一个简单的表示键值对的二元组,也可以是一个复杂的TreeNode。如果是一个一个简单的二元组,则可以通过Node的next域构成构成一个链表。

  transient Node<K,V>[] table;
 

当需要遍历Map的时候,建议使用entrySet域来进行遍历,而不是keySet。因为entrySet其实返回的是一个特殊的set,这个set并未保存任何元素,而是定义了一个特殊的迭代器,这个迭代器直接遍历map中的table,因此能直接得到一个entry的键和值,也就是说,使用entrySet进行遍历的时候,一次遍历即可。(hash冲突除外)。而使用keyset得到的只是key的set,使用key去获取value的时候,还需要进行一次查找。

 

如果只需要值,那么就调用values方法,此方法返回一个特殊的集合,它保存了一个entryset,并使用entryset的迭代器对table进行访问,因此效率也是很高的。

 

方法详述

  • comparableClassFor
    Class<?> comparableClassFor(Object x)

    获取对象x的可比较的class,即尝试从对象x中找到一个Comparable<x.getClass()> 对象。

    首先检查对象x是否是一个comparable的实例:

    if (x instanceof Comparable)

    如果是的话,获取x的class,顺便检查一下是否是String,因为Stirng是用的最多的,顺便加个速。

    如果不是String类,那么就获取此类直接实现的接口(注意,一定是直接实现的)。

    c.getGenericInterfaces())

    然后判断每个父接口是否是参数化类型,且参数化类型的具体类型为compare:

    if (((t = ts[i]) instanceof ParameterizedType) &&

    ((p = (ParameterizedType)t).getRawType() ==

    Comparable.class)

    如果是的话,取出此参数化类型的实际参数类型,如果确实存在,且参数类型和对象x的类型相同,那么这个父接口就是最终要找的comparable接口了。

    (as = p.getActualTypeArguments()) != null &&

    as.length == 1 && as[0] == c) //

  • tableSizeFor

          int tableSizeFor(int cap) int n = cap - 1; n |= n >>> 1; n |= n
    >>> 2; n |= n >>> 4; n |= n >>> 8; n |= n >>>
    16; return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY
    : n + 1;

    这段代码非常巧妙,通过位移和或运算计算出比cap大的最小的2的N次方的值。
    第一行:cap-1是为了解决cap本来就是2的N次方的问题。

    然后进行一次右移,一次右移的效果是:如果某一为本来是1,那么一次位移并或之后,它的低一位也会变成1.这样就将一个1变为2个1了。如果本来是0,那么还是0.

    第一步已经将一个1变为2个1了,那么第二步右移两位,就能将两个1变为4个1,接着变为8个1,16个1,最多不超过32个1.

    这个数字最终的效果是,从低往高看,后面的位数上全是1,然后这个数加1,就是原始的cap的2的N次方最小值了。

  • putVal

    第一步:找到带加入的key所在的桶,使用的办法是用桶数组的大小减1然后和hey的哈希值进行与,这其实是让key的哈希值对桶的大小取余的简便操作,提升了效率。

    第二步:如果桶中当前没有元素,则加入,完成。如果桶中已经有值了,说明发生了hash冲突,此时需要将新加入的值沿着桶中已有的值往下排,构成一个链表。

    在第二中,如果一个桶中的元素超过了一个阀值,默认为8,则不再使用链表来保存桶中的元素,而是改成用二叉查找树来保存,以提高检索效率。

    如果桶中的元素当前已经是一个二叉查找树了,那么就加新元素加入到树中。

    加入一个新元素之后,需要检查Map的数量是否满足填装因子的限制,如果不满足了,需要进行重新hash。

HashMap学习笔记的更多相关文章

  1. HashMap 学习笔记

    先摆上JDK1.8中HashMap的类注释:我翻译了一下 /** * Hash table based implementation of the <tt>Map</tt> i ...

  2. Java HashMap学习笔记

    1.HashMap数据结构 在java编程语言中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可以用这两个基本结构来构造的,HashMap也不例外.HashMap实际 ...

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

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

  4. java集合类学习笔记之HashMap

    1.简述 HashMap是java语言中非常典型的数据结构,也是我们平常用的最多的的集合类之一.它的底层是通过一个单向链表(Node<k,v>)数组(也称之为桶bucket,数组的长度也叫 ...

  5. HashMap源码剖析及实现原理分析(学习笔记)

    一.需求 最近开发中,总是需要使用HashMap,而为了更好的开发以及理解HashMap:因此特定重新去看HashMap的源码并写下学习笔记,以便以后查阅. 二.HashMap的学习理解 1.我们首先 ...

  6. Redis学习笔记4-Redis配置详解

    在Redis中直接启动redis-server服务时, 采用的是默认的配置文件.采用redis-server   xxx.conf 这样的方式可以按照指定的配置文件来运行Redis服务.按照本Redi ...

  7. 《Java学习笔记(第8版)》学习指导

    <Java学习笔记(第8版)>学习指导 目录 图书简况 学习指导 第一章 Java平台概论 第二章 从JDK到IDE 第三章 基础语法 第四章 认识对象 第五章 对象封装 第六章 继承与多 ...

  8. [原创]java WEB学习笔记109:Spring学习---spring对JDBC的支持:使用 JdbcTemplate 查询数据库,简化 JDBC 模板查询,在 JDBC 模板中使用具名参数两种实现

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  9. spark学习笔记总结-spark入门资料精化

    Spark学习笔记 Spark简介 spark 可以很容易和yarn结合,直接调用HDFS.Hbase上面的数据,和hadoop结合.配置很容易. spark发展迅猛,框架比hadoop更加灵活实用. ...

随机推荐

  1. nginx+tomcat+memcached搭建服务器集群及负载均衡

    在实际项目中,由于用户的访问量很大的原因,往往需要同时开启多个服务器才能满足实际需求.但是同时开启多个服务又该怎么管理他们呢?怎样实现session共享呢?下面就来讲一讲如何使用tomcat+ngin ...

  2. Jquery中dialog属性小记

    代码如下: $('#dialogDiv').dialog( { hide:true, //点击关闭是隐藏,如果不加这项,关闭弹窗后再点就会出错. autoOpen:false, height:380, ...

  3. c#之线程入门

    C#支持通过多线程并行地执行代码,一个线程有它独立的执行路径,能够与其它的线程同时地运行.一个C#程序开始于一个单线程,这个单线程是被CLR和操作系统(也称为“主线程”)自动创建的,并具有多线程创建额 ...

  4. libusb简介

    概述 libusb是一个C库,它提供了通用的访问USB设备. 它的目的是供开发人员使用方便的生产与USB通信硬件的应用程序. 可移植的: 使用一个跨平台API,它提供了访问USB设备在Linux上,O ...

  5. CListBox控件基本功能

    创建CListBox对象 CListBox m_ListBox;关联控件 ,同时注意行数从  0  开始计算 1.向控件中添加内容 int AddString(LPCTSTR lpszItem ); ...

  6. 2013 多校联合2 D Vases and Flowers (hdu 4614)

    Vases and Flowers Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others ...

  7. 按钮点击效果jquery

    <html><head> <meta charset="UTF-8"> <title>QQ</title> <me ...

  8. 2016年9月3日 文成小盆友python-num18 - django进阶一

    一.深入django的路由系统 下面为django的请求生命周期 下面来看下整个生命周期中的路由系统: 在Django的urls中我们可以根据一个URL对应一个函数名来定义路由规则如下: " ...

  9. [kuangbin带你飞]专题十 匹配问题 二分图最大权匹配

    二分图最大权匹配有km算法和网络流算法 km算法模板默认解决最大权匹配的问题 而使用最小费用最大流 是解决最小权匹配问题 这两种办法都可以求最大最小权 需要两次取反 TAT 感觉讲km会很难的样子.. ...

  10. Android的理解

    从组件的角度来考虑 Activity------------------Service-----------------Broadcast Receiver---------------------- ...