HashMap 学习 (JDK8)
1.hashmap中hash函数的实现中,异或运算操作的结果是什么,为什么要做这样的异或运算
- static final int hash(Object key) {
- int h;
- return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
- }
假设h是 1000010001110001000001111000000,h>>>16的结果就是一个新的32位数,高16位为0,低16位为h的高16位,这个新数记为q,h^q的结果记为r,以方便描述
由于异或运算的特点,r的高16位就是h的高16位,r的低16位,就是h的低16位和h的高16位进行异或运算的结果
为什么要这样做呢,因为在putVal函数里,在为newNode找坑时,下标 i = (n - 1) & hash ,之所以要这样去计算i,是因为hash值是一个可能大于table数组大小的值,为了解决越界问题,也可以用取模的方式计算出合适的i,但是取模运算没有与运算效率高,而这里的与运算可以达到类似的效果,让计算出的i不会越界
- 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);
- else {
- Node<K,V> e; K k;
- if (p.hash == hash &&
- ((k = p.key) == key || (key != null && key.equals(k))))
- e = p;
- else if (p instanceof TreeNode)
- 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) // -1 for 1st
- treeifyBin(tab, hash);
- break;
- }
- if (e.hash == hash &&
- ((k = e.key) == key || (key != null && key.equals(k))))
- break;
- p = e;
- }
- }
- if (e != null) { // existing mapping for key
- V oldValue = e.value;
- if (!onlyIfAbsent || oldValue == null)
- e.value = value;
- afterNodeAccess(e);
- return oldValue;
- }
- }
- ++modCount;
- if (++size > threshold)
- resize();
- afterNodeInsertion(evict);
- return null;
- }
同时这也引出一点,就是为什么table的数组被要求是2的幂。
HashMap里table的初始大小是16, 二进制也就是 16-1=15,二进制表示是 1111,和hash值与运算,能保留hash值低4位的值,相当于保留了此前hash的散列结果
如果将HashMap里table的初始大小设置位17,17 - 1 = 16,二进制表示是10000,和hash值与运算,会破坏hash值的本身的结果,显然不会是一个好的散列方式
HashMap 学习 (JDK8)的更多相关文章
- HashMap 学习笔记
先摆上JDK1.8中HashMap的类注释:我翻译了一下 /** * Hash table based implementation of the <tt>Map</tt> i ...
- HashMap 学习心得
1.构造 HashMap 底层数据结构线性数组,HashMap有一个静态内部类Entry,Entry有四个属性,key,value,next,hash Entry就是HashMap键值对实现的一个基础 ...
- Hashmap在JDK8中的提升
HashMap使用key的hashCode()和equals()方法来将值划分到不同的桶里. 桶的数量通常要比map中的记录的数量要稍大.这样 每一个桶包含的值会比較少(最好是一个).当通过key进行 ...
- HashMap学习
HashMap<String, Object> java.util.HashMap<String, Object> 在数组中我们是通过数组下标来对其内容索引的,而在Map中 ...
- HashMap学习笔记
概述 HashMap是Map接口的一个哈希表的实现,内部是一个数组表示的.数组中的元素叫做一个Node,一个Node可以一个是一个简单的表示键值对的二元组,也可以是一个复杂的TreeNod ...
- Java HashMap学习笔记
1.HashMap数据结构 在java编程语言中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可以用这两个基本结构来构造的,HashMap也不例外.HashMap实际 ...
- 走近Java之HashMap In JDK8
HashMap,继承AbstractMap类,实现了Map接口,特性是无序不可重复,其本身的数据结构是数组加链表和红黑树.今天我们就一起来详细了解一下. 首先,需要知道,HashMap中几个关键词的含 ...
- 学习-jdk8 特性
jdk8新特性 Lambda 表达式 Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中.方法引用 − 方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构 ...
- JDK1.8 HashMap学习
1:源码分析 1.1:构造方法 public HashMap(int initialCapacity, float loadFactor) { ) throw new IllegalArgumentE ...
随机推荐
- FixedThreadPool吞掉了异常
为了方便遍描述问题,如下是简化后的 public class RunException { public static void main(String[] args) { ExecutorServi ...
- 【dp】求最长公共子序列
[题目描述] 一个给定序列的子序列是在该序列中删去若干元素后得到的序列.确切地说,若给定序列X=<x1,x2,…,xm>X=<x1,x2,…,xm>,则另一序列Z=<z1 ...
- request 获取body内容
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException ...
- golang中使用ETCD
安装 下载ETCD https://github.com/etcd-io/etcd/releases/ 安装 我下载的是window版,直接解压就可以了,解压后有以下目录 点击etcd.exe运行 然 ...
- Security+高分考过经验分享812分
Security +也是无意中从谷安的宣传单知道的,本来就是想从事安全的行业,而且Security +含金量高,是国际认可的认证就想着去考一考试试. 大概从2018.12开始正式准备的,前面时间都是停 ...
- 浅谈Kubernetes生产架构
注意本文,只是笔者针对Kubernetes生产环境运行的一些关于架构设计和实现方案的总结,内容很粗糙,同时也会不断完善. 首先,我们来梳理下Kubernetes生产架构,其设计适用于绝大多数环境.如下 ...
- 03--STL序列容器(Deque)
一:Deque双端队列<头尾操作> stack和queue是在Deque的基础上改进的,所以先介绍双端队列Deque deque是“double-ended queue”的缩写,和 ...
- 目前的.NET 主流的后端ORM框架
转自:https://www.cnblogs.com/yeminglong/p/9518438.html 推荐一些常用的asp.net ORM框架 SqlSugar (国内) Dos.ORM (国内 ...
- unicorn与nginx通讯--[ruby unix socket]
[龍昌博客] http://www.xefan.com/archives/84146.html unicorn是如何与nginx通讯的——介绍ruby中的unix socket Ruby 应用服务典型 ...
- 如何在Eclipse中创建web项目并使用tomcat8 运行servlet开发简单的动态网页?
今天花了一天时间.因为用eclipse没多久,不是很熟悉使用,看的教程又是使用myeclipse的,但是eclipse相对没有myeclipse灵活,所以在网上找了很多资料,最后算是可以实现了.新手可 ...