JDK1.8  HashMap源码分析

用到的符号:

^异运算:两个操作数相同,结果是;两个操作数不同,结果是1。

&按位与:两个操作数都是1,结果才是1。

一、HashMap概述

在JDK1.8之前,HashMap采用数组+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。而JDK1.8中,HashMap采用数组+链表+红黑树(二叉树的优化实现是一种平衡二叉树,可以降低数的深度)实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间。

jdk1.8之前的hashmap都采用上图的结构,都是基于一个数组和多个单链表,hash值冲突的时候,就将对应节点以链表的形式存储。如果在一个链表中查找其中一个节点时,将会花费O(n)的查找时间,会有很大的性能损失。到了jdk1.8,当同一个hash值的节点数不小于8时,不再采用单链表形式存储,而是采用红黑树。

二、了解Hash函数

我们先了解一下Hash的源码:

代码执行过程:如果key为空,返回0;如果key不为空,返回原hash值和原hash值无符号右移16位的值按位异或的结果。(把低16位和高16位进行异或运算)。因为低位重复概率计算大,低位和高位异或运算可以提交数组的利用率,使数组分布均匀。

按位异或就是把两个数按二进制,相同就取0,不同就取1。

比如:0101 ^ 1110 的结果为 1011,异或的速度是非常快的。

把一个数右移16位即丢弃低16为,就是任何小于216的数,右移16后结果都为0(2的16次方再右移刚好就是1)。

任何一个数,与0按位异或的结果都是这个数本身。

所以这个hash()函数对于非null的hash值,仅在其大于等于216的时候才会重新调整其值。

但是调整后又什么好处呢?

我们先看下put的时候,这个hash值是怎么处理(部分源码)的:

在寻找桶位的时候,这个hash值为与上table的zise-1,初始为16,我们就拿16来举例.

以为算法是hashValue & size - 1 ,此时size-1=15的二进制为 1 1 1 1 ,也就是任意类似16进制0x?0(二进制最后四位为0000)的hash值,都会被存储到位置为0的桶位上,一个桶中的元素太多,就一定会降低其性能。我们知道HashMap是一个数组+链表,就是在下标相同的位置下面挂一个单项的链表,那数组的下标需要计算出来,必须保证在一定的范围内,是通过【(n-1)&hash】计算机计算的是二进制,比如数组大小必须是2的N次幂,权重是0.75,数组初始值是16,权重等于12(16*0.75),当等于12数组会扩容。扩容之后对数组进行重新分配。当链表的大小大于8的时候会转化为红黑树。数组下标计算方式:(0101010101010101010101010101&00000000000000000001111)以16来说,十六进制的二进制表示后面的0,N-1的二进制结尾是1111,两者进行与操作最大值是1111,1111的16十六进制是15,然后把Node节点放入这个位置,这样来计算下标。

判定程序员等级,HashMap就够了的更多相关文章

  1. 判定Java程序员等级,HashMap就够了

    JDK1.8  HashMap源码分析 用到的符号: ^异运算:两个操作数相同,结果是;两个操作数不同,结果是1. &按位与:两个操作数都是1,结果才是1. 一.HashMap概述 在JDK1 ...

  2. 惊呆!Java程序员等级一览

      凡人:买本书凑凑热闹,听得多写的少,过段时间就把老师教的都忘了.这个阶段是刷掉人最多的阶段,也是从凡人到程序员本质区别的阶段.你的日后成就在于你的习惯与态度.隔一段时间整理自己的知识体系是重中之重 ...

  3. [zz]论程序员

    g9老大多年前的趣文: 论程序员 根据钱钟书先生的<论文人>胡改的.聊搏一笑,文责不负.程序员是可嘉奖的,因为他虚心,知道上进,并不拿身分,并不安本分.真的,程序员对于自己,有时比旁人对于 ...

  4. 【转】成为Java顶尖程序员 ,看这11本书就够了

    成为Java顶尖程序员 ,看这11本书就够了 转自:http://developer.51cto.com/art/201512/503095.htm 以下是我推荐给Java开发者们的一些值得一看的好书 ...

  5. 程序员周末阿里面试,5分钟就被一道题秒杀:HashMap与Hashtable

    你们可能会想,我这么菜的吗?5分钟都坚持不了? 本文说起来会有点尴尬,毕竟这是我曾经经历过的故事 那时候的我还真菜,每天写着 if/ for 及一些简单的业务逻辑代码,虽工作有些日子了,但技术水平还停 ...

  6. 【转】成为Java顶尖程序员 ,看这10本书就够了

    “学习的最好途径就是看书“,这是我自己学习并且小有了一定的积累之后的第一体会.个人认为看书有两点好处: 1.能出版出来的书一定是经过反复的思考.雕琢和审核的,因此从专业性的角度来说,一本好书的价值远超 ...

  7. 成为Java顶尖程序员 ,看这11本书就够了(转)

    学习的最好途径就是看书",这是我自己学习并且小有了一定的积累之后的第一体会.个人认为看书有两点好处: 1.能出版出来的书一定是经过反复的思考.雕琢和审核的,因此从专业性的角度来说,一本好书的 ...

  8. 想要薪资20-30K,Python程序员认真敲代码就够了!

    在这个年代,互联网的飞速壮大大家有目共睹,除了表露出的公共受益,其中计算机编程者也是做出了巨大的贡献,即使外国编程语言仍旧属于领导者,但是在互联网的壮大下,我们这是"地球村",国内 ...

  9. 成为Java顶尖程序员 ,看这11本书就够了

    以下是我推荐给Java开发者们的一些值得一看的好书.但是这些书里面并没有Java基础.Java教程之类的书,不是我不推荐,而是离我自己学习 Java基础技术也过去好几年了,我学习的时候看的什么也忘了, ...

随机推荐

  1. Oracle12c:自动分区表

    为什么要创建oracle分区表? 一般情况下,如果不分区,则每次查询的对象都是一整张表,如果采用了表分区,那么可以根据具体的分区字段当作条件来避免扫描整张表,减少IO的扫描以提高表的查询速度. 新建( ...

  2. wrapper x64 版本发布到centos

    背景: 项目需要在spark任务提交服务器节点上自动提交任务到spark集群上.因此创建了一个固定时间监控任务项目,使用timer定时监控oracle数据库中是否有spark提交任务,如果有spark ...

  3. urllib.parse.urlencode

    urllib.request.urlopen(url,data,timeout) 其中如果data被赋值,则请求的方式就会由get转为post,而post需要提供一些待处理的数据. 这些待处理的数据需 ...

  4. AFNetworking 源码解读

    最近开始看第三方库优秀源码的计划,这是第一个,AFNetworking来和大家分享一下. AFNetworking 是一个十分优秀的网络框架,简单易用. 在开始之前,最好先了解一下NSURLSessi ...

  5. drupal 8 查看数据库用户名密码

    一.查看网站数据库名.密码 在已安装网站下 例如:我安装了一个d8radix的网站,此网站/home/jx/www/d8radix/sites/default/setting.php文件里面 数据库名 ...

  6. [LeetCode] Minimum Window Subsequence 最小窗口序列

    Given strings S and T, find the minimum (contiguous) substring W of S, so that T is a subsequence of ...

  7. [LeetCode] Super Washing Machines 超级洗衣机

    You have n super washing machines on a line. Initially, each washing machine has some dresses or is ...

  8. Python 字符串常见的27个操作

    有字符串 mystr = "hello world itcast and itcastcpp",以下是常见的操作: 1. mystr.find(str, start=0, end= ...

  9. sed和awk的使用

  10. Anaconda入门安装教程

    Anaconda 是什么? Anaconda 是一个可用于科学计算的 Python 发行版,支持 Linux.Mac.Windows系统,内置了常用的科学计算包.它解决了官方 Python 的两大痛点 ...