总述:通过一定的算法,将key的hashcode转换成数组的index;将key,value,hash等信息保存在数组对应的index位置上.
问题:
1.某些key的hashcode相同
2.hashcode不同,但一定算法后映射到数组的index相同
这个就是常说的hashcode冲突问题.
1.HashMap涉及的数据结构
Entry[] ;
//Entry数组:存储HashMap元素的地方.
//Entry
//1.封装了key;value;
//2.本身是一个单向链表;包含hash值;next;指针;
static class Entry<K,V> implements Map.Entry<K,V> {
final K key;
V value;
final int hash;
Entry<K,V> next;
/**
* Create new entry.
*/
Entry(int h, K k, V v, Entry<K,V> n) {
value = v;
next = n;
key = k;
hash = h;
}
....
}
2.存储的过程:
通过hashcode得到index后.存储的不仅仅是该元素的key,value,hash.还有指向下一个Entry的引用.如果出现了hashcode冲突问题.则新建一个Entry;将该Entry的nex指针指向已存在的Entry.
public V put(K key, V value) {
K k = maskNull(key);
int hash = hash(k); //算hash
int i = indexFor(hash, table.length); //取对应的index
//该index对应的Entry可能不是一个Entry,而是一个Entry链.
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
if (e.hash == hash && eq(k, e.key)) { //已存在,则更新值.
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, k, value, i); //该位置还空;或者位置不空,但已有Entry(hashcode冲突)
return null;
}
void addEntry(int hash, K key, V value, int bucketIndex) {
//取到当前位置上的Entry,可能是null
Entry<K,V> e = table[bucketIndex];
//创建新Entry,next指向已存在的
table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
if (size++ >= threshold)
resize(2 * table.length);//扩容.
}
3.取值的过程
还是hash-index-Entry的过程.不是直接return该index上Entry;而要检查Entry链上真正对应的那个
public V get(Object key) {
Object k = maskNull(key);
int hash = hash(k); //取hash
int i = indexFor(hash, table.length);//取index
//取回来的是一个Entry链
Entry<K,V> e = table[i];
//遍历
while (true) {
if (e == null)
return null;
if (e.hash == hash && eq(k, e.key)) //真正要get的那个
return e.value;
e = e.next; //指针后移到下一个Entry
}
}
算个复习吧.没看过的看看.笔试面试很常见.
分享到:
相关推荐
HashMap的用法---马克-to-win java视频的详细描述与介绍
hashmap的原理啊思想。
在这个主题中,我们将深入探讨HashMap类,它是Java集合框架中的一个关键组件,特别是在标题“20-集合框架020-HashMap-1080P 高清-AVC20”和描述中所提到的内容。 HashMap是Java.util包中的一个类,它实现了Map接口...
本项目“hashmap-thread-test”显然是为了测试和展示这一特性。 ### Java HashMap 的特性 1. **非线程安全**:`HashMap`不是线程安全的,因为它没有内置的同步机制来保护并发访问。当多个线程同时修改`HashMap`时...
JAVA之hashmap源码分析 Mobile-Dev-Analysis Analysis of android or java 红岩网校工作站移动开发部学员分组学习 为了让大家学的更加坚固,采取小组学习的方式帮助大家学习,同时在学习研究的过程中需要不断的做...
java代码-使用java解决手写hashMap的源代码 ——学习参考资料:仅用于个人学习使用!
2. **冲突解决**:当两个或更多键的哈希值相同时,HashMap需要一种策略来处理这种情况。常见的方法是使用链表链接所有冲突的键值对,或者采用二次探测、双哈希等方法来寻找其他空位。 3. **动态扩容**:随着键值对...
《C语言实现的哈希映射——c_hashmap-master中的keys操作详解》 在计算机科学领域,哈希映射(Hash Map)是一种高效的数据结构,它通过特定的哈希函数将键(Key)映射到数组的索引位置,从而实现快速的查找、插入和...
hashmap源码 Excellent-Blog-share Welcome to share excellent blogs . 当你的能力还驾驭不了你的目标时,就应该沉下心来历练 当你的才华还撑不起你的野心时,那你就应该静下心来学习 #目录 ###附录 java系列 java8...
hashmap的get流程 - 副本
- `Hashtable` 和 `HashMap` 为了提高性能,会尽量避免哈希冲突的发生,即多个对象具有相同的 `HashCode`。 - 为了减少冲突,可以通过优化 `HashCode` 的计算方法,使不同的对象尽可能获得不同的 `HashCode` 值。 ...
通过以上分析,我们可以了解到实现一个自定义的HashMap涉及许多细节和技巧,包括哈希函数的设计、冲突解决策略的选择、以及性能优化等。在实际编程中,理解这些概念有助于我们更好地使用和定制HashMap,满足特定需求...
`HashMap`的内部实现会调用键对象的`hashCode()`方法,然后对其进行一定的转换操作,以便更好地分布数据并减少冲突。 #### 三、高位扩展与低位扩散 在`HashMap`中,对于计算得到的哈希码,官方文档提到一个非常...
### HashMap多线程解决方案 #### 一、引言 在多线程环境下,Java的`HashMap`类在处理并发操作时容易出现线程安全问题。本文档深入探讨了`HashMap`在多线程环境中可能遇到的安全问题,并提出了一系列可行的解决方案...
在Java编程语言中,HashMap是集合框架中一个重要的类,用于存储键值对的数据结构。这个实例教程将深入解析HashMap的遍历方法及其源代码,帮助开发者更好地理解和使用HashMap。以下是对这个主题的详细讲解: 1. **...
- 分析`Hashes.pas`文件可以深入了解这些哈希表的实现细节,包括它们的内部结构、冲突解决策略和性能优化技巧。 - 对源代码的研究可以帮助开发者学习如何在Delphi中高效地实现自定义的哈希表。 总之,这个Delphi...
当两个键的哈希值相同,导致冲突时,HashMap使用链地址法来解决,即将冲突的键值对链接成一个链表。 3. **哈希冲突处理** 在HashMap中,如果两个键的哈希值相同但并不相等,它们会在同一个桶(数组索引位置)形成...
如果有,就需要进行冲突解决。Java的HashMap采用链地址法处理冲突,即将所有哈希冲突的键值对挂在同一个桶的链表上。 3. 查找键值对时,首先计算键的哈希码,找到对应的桶,然后遍历链表,使用`equals()`方法比较键...