- 浏览: 216822 次
- 性别:
- 来自: 北京
文章分类
当添加的元素的key为null时,hashmap会先获取内部entry数组的第一个对象判断其key是否为null。如果不为null,通过entry.next查找下一个对象。直到遍历结束前找到key为null的对象。然后将新值替换旧值,并将旧值返回。如果未找到key为null的对象。则创建一个新的Entry对象。该对象的hash为0,key为null,value为传入的value。next指向第一个元素。
private V putForNullKey(V value) {
for (Entry<K,V> e = table[0]; e != null; e = e.next) {
if (e.key == null) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(0, null, value, 0);
return null;
}
void addEntry(int hash, K key, V value, int bucketIndex) {
Entry<K,V> e = table[bucketIndex];
table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
if (size++ >= threshold)
resize(2 * table.length);
}
如果添加元素的key不为null。则先获取该对象的hashcode,然后对这个对象做hash操作。
接着通过将得到的hash值与hashmap的entry数组长度-1做与操作。得到应当存放数组的位置。但是这也可能会出现key不同,但是存放的数组位置相同,这被称为hash碰撞。因此hashmap采取的办法是拿到插入位置的对象,进行比较key值是否相同。若是不同则向后遍历,直到找到相同的为止。找到后进行元素的替换,若是找不到就新生成一个Entry,entry对象的next指向上面获取的位置i。
相关代码
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
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;
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;
}
private V putForNullKey(V value) {
for (Entry<K,V> e = table[0]; e != null; e = e.next) {
if (e.key == null) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(0, null, value, 0);
return null;
}
void addEntry(int hash, K key, V value, int bucketIndex) {
Entry<K,V> e = table[bucketIndex];
table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
if (size++ >= threshold)
resize(2 * table.length);
}
如果添加元素的key不为null。则先获取该对象的hashcode,然后对这个对象做hash操作。
接着通过将得到的hash值与hashmap的entry数组长度-1做与操作。得到应当存放数组的位置。但是这也可能会出现key不同,但是存放的数组位置相同,这被称为hash碰撞。因此hashmap采取的办法是拿到插入位置的对象,进行比较key值是否相同。若是不同则向后遍历,直到找到相同的为止。找到后进行元素的替换,若是找不到就新生成一个Entry,entry对象的next指向上面获取的位置i。
相关代码
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
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;
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;
}
发表评论
-
JVM启动时指定-Dfile.encoding="UTF8"的作用
2013-10-17 13:50 2413简单来说就是指定JVM默认的编码方式 java io中很多方法 ... -
java多线程 小记
2012-04-15 14:49 0thread join的方法 http://blog.csdn ... -
浅析多线程
2012-04-08 22:35 0线程组 线程是被 ... -
多线程意外中断处理
2012-04-08 20:54 0本文转自:http://peirenlei.iteye.com ... -
多线程项目学习
2012-04-08 20:35 0线程组的作用: ThreadGroup类中的某些方法,可以对线 ... -
java 静态成员变量的内存分配
2012-04-06 10:28 0静态成员变量是属于类变量,即当JVM加载class文件到虚拟机 ... -
深度克隆与浅克隆
2012-04-05 16:31 1179要想实现某个对象的克隆需要该对象实现java.lang.Clo ... -
修改图片大小并添加水印
2012-03-29 13:47 1330import java.awt.*; import java. ... -
JVM的内存分配
2012-03-16 10:06 0Java里的堆(heap)栈(stack)和方法区(metho ... -
几种classloader的加载范围
2012-02-28 12:43 1379Bootstrap class loader:最顶级的clas ... -
利用正则表达式获取网页中多处重复出现的标签数据
2012-02-21 11:21 2741public static void main(String[ ... -
标准的URLConnection请求
2012-01-13 16:39 0只写了主要的代码 URL url = new URL(urlS ... -
常用的ClassLoader的加载范围
2012-01-13 13:53 1440WebAppClassLoader装载器装作文件的范围: 会加 ... -
ClassLoader.getSystemClassLoader().loadClass()和Class.forName()的区别
2012-01-13 13:08 0class A { static { System.ou ... -
httpClient超时解决办法
2012-01-12 16:47 0DefaultHttpClient: 请求超时 httpcli ... -
项目中的使用技巧小记
2012-01-10 21:11 618实现数据在多线程之间的共享: 因为线程的成员变量是各个该线程实 ... -
ThreadLocal
2012-01-10 08:55 1452ThreadLocal是实现线程范围内的数据共享,即不同线程获 ... -
线程加锁优化
2012-01-08 13:19 0实际上,在某些classes中,这种instance方法的同步 ... -
实现多线程使用继承Thread类和Runnable的原因
2012-01-03 15:09 1407我们都知道实现多线程的两种方式,一种是继承Thread类,另一 ... -
一个简单的socket编程实例
2011-12-28 10:50 1639转正于http://www.cnblogs.com/linzh ...
相关推荐
HashMap是Java编程语言中一个非常重要的数据结构,它属于集合框架的一部分,主要用于存储键值对(Key-Value)数据。HashMap在内部实现上基于哈希表,也称为散列表,它提供了一种快速查找、插入和删除数据的方法,...
HashMap的一个数据结构 锁升级:锁升级过程 resize的过程在开发中 怎么保证容器它线程安全后就是数据插入过程使用的头插法 但是头插法会造成一些问题等等等等的那个等等的那个等等的那个等等的那个等等的那个等等的...
- 如果节点p是TreeNode(表示链表已转换为红黑树),putVal会调用putTreeVal方法,在红黑树中插入新节点,保持树的平衡。 - 如果节点p是普通Node且哈希值相同但键不同,新数据会被添加到链表的末尾。当链表长度...
下面我们将深入探讨 HashMap 的数据结构、 put 方法的实现细节和 Hash 码的计算过程。 HashMap 的数据结构 HashMap 的数据结构可以分为两部分:数组和链表。数组是 HashMap 的基本结构,链表是数组元素的具体实现...
`addEntry()`方法是HashMap添加新键值对的关键函数。它首先计算键的哈希码,然后找到对应数组索引,如果该位置已经有元素存在,则将新的键值对插入到链表头部。同时,`addEntry()`会检查当前HashMap的大小是否超过了...
当向HashMap中添加元素时,系统会根据键的哈希值计算出其在数组中的位置,并将元素存放在该位置。如果该位置已有元素,则将新元素以链表形式连接到已有元素之后。 #### 二、哈希算法 为了提高查找效率,HashMap...
HashMap 在 put 数据时是如何找到要存放的位置的? 在使用 HashMap 时,我们常常会问自己,HashMap 是如何...这个过程保证了 key 得到的数组索引下标尽可能分撒,降低了一开始往 HashMap 中添加数据时链表的产生几率。
在Java中,HashMap是一种广泛使用的数据结构,它基于...总的来说,Java中的HashMap是一个灵活且高效的数据结构,适用于快速的查找和插入操作。理解其基于哈希的工作原理对于充分利用HashMap的性能优势是非常有帮助的。
Java中的HashMap是一个非常重要的数据结构,它实现了Map接口,提供了键值对的高效存储和访问。HashMap基于哈希表(也称为散列表)原理工作,它允许用户通过键(Key)快速查找对应的值(Value)。在HashMap中,键和值...
总的来说,理解HashMap中红黑树插入节点的调整过程需要深入理解红黑树的性质和旋转操作,同时熟悉HashMap源码中的编码风格和变量命名规则。通过这些知识,我们可以更好地掌握HashMap在处理大数据量时如何保持高效...
在JDK 7中,HashMap的put过程相对简单,也是通过哈希值定位到桶,如果桶为空则直接插入,否则将新元素添加到链表的末尾。然而,由于HashMap是非线程安全的,如果多个线程同时put可能导致死循环的问题。这是因为当两...
由于HashMap不会自动清除过期或不再使用的条目,开发者需要考虑何时以及如何更新或清除缓存中的数据。此外,虽然HashMap提供了高效的内存访问,但如果缓存中存储了大量或过大的对象,可能会导致垃圾回收器的压力增大...
易语言HashMap类是一种在易语言编程环境中实现的高效数据结构,它主要用于存储键值对(key-value pairs),提供快速的数据存取。HashMap类基于哈希表(Hash Table)原理,通过计算键的散列值来确定数据在内存中的...
循环次数可以理解为模拟插入操作的次数,在这个过程中,可能会涉及到HashMap的扩容和哈希冲突的解决。负载因子为0.75时,哈希表长度(maptablelen)为256,而负载因子为0.3时,哈希表长度则为512。这说明在负载因子...
HashMap是Java编程语言中的一种内置数据结构,它提供了O(1)的平均时间复杂度来执行查找、插入和删除操作,这使得它成为构建词典查询系统的理想选择。 首先,我们来深入理解HashMap的工作原理。HashMap基于哈希表的...
当向 HashMap 中插入一个键值对时,会先计算键的哈希值,通过哈希值与数组长度进行按位与运算(hash % array.length),得到的余数值作为数组的索引。如果该索引位置已经有元素存在,说明发生了哈希冲突,此时会将...
在学习过程中,可以重点关注哈希函数的设计、链表的插入与查找以及扩容的实现,这些都是HashMap性能的关键因素。同时,它也可以作为进一步研究和优化哈希表的基础,例如探索更高效的哈希算法或者优化扩容策略。
红黑树在 HashMap 中主要用于存储有序的数据,并且可以快速地进行搜索、插入和删除操作。HashMap 中元素的存储规则是按照 key 的 hash 值找到下标,然后判断该位置是否有元素,如果有就将尾节点的 Node 的 next 指向...
然而,在实际应用过程中,这两种数据结构有着本质的不同,下面将详细介绍这些差异。 #### 1. 历史背景及实现原理 - **Hashtable**:该类继承自`Dictionary`类,并且实现了`Map`接口。它最早出现在Java 1.0版本中,...
HashMap是Java编程语言中最常用的集合类之一,它提供了一种基于键值对(key-value pair)的数据存储方式,具有高效查找、插入和删除操作。在Java 8中,HashMap的实现有了很多改进,以提高性能和空间利用率。下面我们...