/**
* Returns the value to which the specified key is mapped,
* or if this map contains no mapping for the key.
*
* 获取key对应的value
*/
public V get(Object key) {
if (key == null)
return getForNullKey();
//获取key的hash值
int hash = hash(key.hashCode());
// 在“该hash值对应的链表”上查找“键值等于key”的元素
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
return e.value;
}
return null;
} /**
* Offloaded version of get() to look up null keys. Null keys map
* to index 0.
* 获取key为null的键值对,HashMap将此键值对存储到table[0]的位置
*/
private V getForNullKey() {
for (Entry<K,V> e = table[0]; e != null; e = e.next) {
if (e.key == null)
return e.value;
}
return null;
} /**
* Returns <tt>true</tt> if this map contains a mapping for the
* specified key.
*
* HashMap是否包含key
*/
public boolean containsKey(Object key) {
return getEntry(key) != null;
} /**
* Returns the entry associated with the specified key in the
* HashMap.
* 返回键为key的键值对
*/
final Entry<K,V> getEntry(Object key) {
//先获取哈希值。如果key为null,hash = 0;这是因为key为null的键值对存储在table[0]的位置。
int hash = (key == null) ? 0 : hash(key.hashCode());
//在该哈希值对应的链表上查找键值与key相等的元素。
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
}
return null;
} /**
* Associates the specified value with the specified key in this map.
* If the map previously contained a mapping for the key, the old
* value is replaced.
*
* 将“key-value”添加到HashMap中,如果hashMap中包含了key,那么原来的值将会被新值取代
*/
public V put(K key, V value) {
//如果key是null,那么调用putForNullKey(),将该键值对添加到table[0]中
if (key == null)
return putForNullKey(value);
//如果key不为null,则计算key的哈希值,然后将其添加到哈希值对应的链表中
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
//如果这个key对应的键值对已经存在,就用新的value代替老的value。
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
} modCount++;
addEntry(hash, key, value, i);
return null;
}

get:通过获取key的hashcode,然后调用 hash() 获得hash值,然后在“该hash值对应的链表”上查找“键值等于key”的元素。

put:通过获取key的hashcode,然后调用 hash() 获得hash值,然后将其添加到哈希值对应的链表中(如果key为null,则将该键值对存储到table[0]中),如果这个key对应的键值对已经存在,就用新的value代替老的value。

HashMap.put()和get()原理的更多相关文章

  1. 详解HashMap的内部工作原理

    本文将用一个简单的例子来解释下HashMap内部的工作原理.首先我们从一个例子开始,而不仅仅是从理论上,这样,有助于更好地理解,然后,我们来看下get和put到底是怎样工作的. 我们来看个非常简单的例 ...

  2. 关于HashMap put元素的原理

    HashMap集合put元素的原理:(1)计算key的hashCode(2)将key的hashCode作为计算因子,通过哈希算法计算HashMap的数组下标index(3)如果index下标的数组元素 ...

  3. HashMap的底层实现原理

    HashMap的底层实现原理1,属性static final int MAX_CAPACITY = 1 << 30;//1073741824(十进制)0100000000000000000 ...

  4. HashMap底层实现及原理

    注意:文章的内容基于JDK1.7进行分析.1.8做的改动文章末尾进行讲解.       一.先来熟悉一下我们常用的HashMap: 1.HashSet和HashMap概述 对于HashSst及其子类而 ...

  5. Map实现之HashMap(结构及原理)(转)

    java.util包中的集合类包含 Java 中某些最常用的类.最常用的集合类是 List 和 Map.List 的具体实现包括 ArrayList 和 Vector,它们是可变大小的列表,比较适合构 ...

  6. HashMap和ConcurrentHashMap实现原理及源码分析

    HashMap实现原理及源码分析 哈希表(hash table)也叫散列表,是一种非常重要的数据结构,应用场景及其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表, ...

  7. Java集合:HashMap底层实现和原理(源码解析)

    Note:文章的内容基于JDK1.7进行分析.1.8做的改动文章末尾进行讲解. 一.先来熟悉一下我们常用的HashMap: 1.概述 HashMap基于Map接口实现,元素以键值对的方式存储,并且允许 ...

  8. HashMap底层结构、原理、扩容机制

    https://www.jianshu.com/p/c1b616ff1130 http://youzhixueyuan.com/the-underlying-structure-and-princip ...

  9. HashMap内部结构及实现原理

    简单介绍 在研究HashMap之前,我们先大概了解下其他数据结构在新增,查找等基础操作执行性能 数组:采用一段连续的存储单元来存储数据.对于指定下标的查找,时间复杂度为O(1):通过给定值进行查找,需 ...

  10. hashmap的一些基础原理

    本文来源于翁舒航的博客,点击即可跳转原文观看!!!(被转载或者拷贝走的内容可能缺失图片.视频等原文的内容) 若网站将链接屏蔽,可直接拷贝原文链接到地址栏跳转观看,原文链接:https://www.cn ...

随机推荐

  1. AS3 内存基础

    1:获取一个对象的字节数: var str:String="ddd啊"; var byte:ByteArray=new ByteArray(); byte.writeMultiBy ...

  2. uoj #58【WC2013】糖果公园

    http://uoj.ac/problem/58 树上带修莫队模板题 #include<bits/stdc++.h> ; typedef long long i64; ],*ptr=buf ...

  3. P2799国王的魔镜

    链接 想了好久(蒟蒻的不能蒟蒻) 题解: #include<iostream>#include<cstdio>#include<cstring>#include&l ...

  4. Linux下静态库和动态库

    函数库分为静态库和动态库 动态库(格式为libname.so[.主版本号.次版本号.发行号]).在程序编译时并不会被链接到目标代码中,而是在程序运行时才被载入. 静态库是目标文件.a的归档文件(格式为 ...

  5. keystone认证服务

    实验操作平台:OpenStack单节点操作 一.相关概念 1.认证(authentication) 认证是确认允许一个用户访问的进程 2.证书(credentials) 用于确认用户身份的数据 3.令 ...

  6. 第9章 应用层(2)_动态主机配置协议(DHCP)

    2. 动态主机配置协议(DHCP) 2.1 静态地址和动态地址的应用场景 (1)静态地址应用场景 ①IP地址不经常更改的设备(如服务器地址) ②使用有规律的IP地址以便于管理(如学校机房为方便教师管理 ...

  7. Delphi 常用语句

    1.屏蔽Float浮点数出错: Set8087CW(Longword($133f)); 2.Idhttp参数设置: FIdhttp                  := TIdHTTP.Create ...

  8. CVPR 2019 | 用异构卷积训练深度CNN:提升效率而不损准确度

    对于深度卷积神经网络而言,准确度和计算成本往往难以得兼,研究界也一直在探索通过模型压缩或设计新型高效架构来解决这一问题.印度理工学院坎普尔分校的一篇 CVPR 论文则给出了一个新的思路——使用异构的卷 ...

  9. JVM总结-反射

    反射是 Java 语言中一个相当重要的特性,它允许正在运行的 Java 程序观测,甚至是修改程序的动态行为. 举例来说,我们可以通过 Class 对象枚举该类中的所有方法,我们还可以通过 Method ...

  10. c# Color 颜色设置

    #region 笔刷颜色 public SolidColorBrush col(byte a, byte r, byte g, byte b) { #region 颜色说明 //Color.FromA ...