HashMap源码学习
来源:互联网 发布:新开淘宝网店卖什么好 编辑:程序博客网 时间:2024/05/22 10:51
- Lru的意思是先淘汰时间最远的哪一个,LFU则淘汰使用频率最小的哪一个。
- Hashmap
static int indexFor(int h, int length) {
return h & (length-1);
}
相当于%但length要是2的幂。
hashCode()
用来确定对象在hashmap
中的位置,函数返回一个整数,如果a.equals(b)
则a.hashCode()==b.hashCode()
这两个函数一个用来确定对象是否相等,一个在hashMap
中区分元素。hashCode()
和equals()
的默认实现相似是内存地址。
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; } 这个table[0]位置不光存了key==null的值,别的key也可能hash到这个位置
void transfer(Entry[] newTable) { Entry[] src = table; int newCapacity = newTable.length; for (int j = 0; j < src.length; j++) { Entry<K,V> e = src[j]; if (e != null) { src[j] = null; do { Entry<K,V> next = e.next; int i = indexFor(e.hash, newCapacity); e.next = newTable[i]; newTable[i] = e; e = next; } while (e != null); } } } - 重新计算每个元素在表中的位置因为hash()%length中的length发生了变化并不是只要将table[i]中的一串列表直接移到newTable[i]中就行了。 - table[i]中是单链表以null结尾
final Entry<K,V> removeMapping(Object o) { if (!(o instanceof Map.Entry)) return null; Map.Entry<K,V> entry = (Map.Entry<K,V>) o; Object key = entry.getKey(); int hash = (key == null) ? 0 : hash(key.hashCode()); int i = indexFor(hash, table.length); Entry<K,V> prev = table[i]; Entry<K,V> e = prev; // 删除链表中的“键值对e” // 本质是“删除单向链表中的节点” while (e != null) { Entry<K,V> next = e.next; if (e.hash == hash && e.equals(entry)) { modCount++; size--; if (prev == e) table[i] = next; else prev.next = next; e.recordRemoval(this); return e; } prev = e; e = next; } return e; } 这个函数要是在双链表的实现中就可以直接删除了不用再找了。
- 快速失败 fast-fail防止别的线程改变了表的结构
final Entry<K,V> nextEntry() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); Entry<K,V> e = next; if (e == null) throw new NoSuchElementException(); // 注意!!! // 一个Entry就是一个单向链表 // 若该Entry的下一个节点不为空,就将next指向下一个节点; // 否则,将next指向下一个链表(也是下一个Entry)的不为null的节点。 if ((next = e.next) == null) { Entry[] t = table; while (index < t.length && (next = t[index++]) == null) ; } current = e; return e; } 始终保持next为下一个,那么获取下一个就是返回next,next跟新为next的下一个。hasNext()就是检测next是否为null这种设计主要是为了hasNext();
- 迭代器定义在
hashMap
内部他的构造函数为private所以只能有hashMap
调用,迭代器由于是hashMap
的内部类,可以之间操纵hashMap
的内部结构,而next()方法由于生命为public
可以被外部调用。
3、HashMap共有四个构造方法。构造方法中提到了两个很重要的参数:初始容量和加载因子。这两个参数是影响HashMap性能的重要参数,其中容量表示哈希表中槽的数量(即哈希数组的长度),初始容量是创建哈希表时的容量(从构造函数中可以看出,如果不指明,则默认为16),加载因子是哈希表在其容量自动增加之前可以达到多满的一种尺度,当哈希表中的条目数超出了加载因子与当前容量的乘积时,则要对该哈希表进行 resize 操作(即扩容)。
文/Maat红飞(简书作者)
原文链接:http://www.jianshu.com/p/fc9e37ee2afd
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
4、HashMap中key和value都允许为null。
扩容是一个相当耗时的操作,因为它需要重新计算这些元素在新的数组中的位置并进行复制处理。因此,我们在用HashMap的时,最好能提前预估下HashMap中元素的个数,这样有助于提高HashMap的性能。
如果hashmap
中有重复key则第二次插入讲第一次的value覆盖
1 0
- HashMap源码学习
- HashMap源码学习
- HashMap源码学习
- HashMap源码学习笔记
- JAVA源码学习-HashMap
- HashMap源码学习
- HashMap源码学习总结
- HashMap源码学习笔记
- hashmap源码学习整理
- HashMap源码学习1
- JDK源码学习之HashMap
- 关于hashMap的源码学习
- 集合学习--HashMap 源码初探
- TreeMap和HashMap源码学习
- [Java]JDK源码学习(3)HashMap
- JDK源码学习系列08----HashMap
- HashMap和HashTable源码学习笔记
- JDK1.8源码学习之 HashMap.java
- Android ViewPager和Fragment实现顶部导航界面滑动效果
- ExtJs定时消息提示框,类似于QQ右下角提示,ExtJs如何定时向后台发出两个请求并刷新数据实例
- java上位机
- iOS开发 iOS10推送必看(基础篇)
- OJ 奖金
- HashMap源码学习
- Ajax作用及Ajax函数编写
- swift开发教程
- 扒一扒金融BA的蓝瘦香菇
- ViewPager+FragmentPagerAdapter实现微信5.2.1主界面架构
- 设计模式
- 获取文件夹下的文件名生成新的文件&DOC命令想从指定的txt中读出文件名,然后在指定文件夹以及子目录下搜索文件,并拷贝到指定目录
- hduoj1290 附加对于所有切割问题的解析
- iOS10推送必看UNNotificationAttachment以及UNTimeIntervalNotificationTrigger