HashMap源码阅读
来源:互联网 发布:sql进阶 编辑:程序博客网 时间:2024/05/16 09:12
1.HashMap空间申请
Hash默认的初始化空间大小为16字节,最大的空间大小为1073741824字节。HashMap在构造方法中对空间的容量进行初始化。代码如下:
public HashMap(int initialCapacity, float loadFactor) { if (initialCapacity < 0) throw new IllegalArgumentException("Illegal initial capacity: " + initialCapacity); if (initialCapacity > MAXIMUM_CAPACITY) initialCapacity = MAXIMUM_CAPACITY; if (loadFactor <= 0 || Float.isNaN(loadFactor)) throw new IllegalArgumentException("Illegal load factor: " + loadFactor); this.loadFactor = loadFactor; threshold = initialCapacity; init(); }
从代码中,我们可以看出,当我们自定义空间容量超过1073741824字节时候,它默认只给1073741824字节的容量。
2.计算Hash码
在hashMap中,存储都是以键值对的形式来存储的,在我们传入键值对的时候,不是直接存储的,会先对键进行计算,换算成Hash码存储。代码如下:
final int hash(Object k) { int h = hashSeed; if (0 != h && k instanceof String) { return sun.misc.Hashing.stringHash32((String) k); } h ^= k.hashCode(); // This function ensures that hashCodes that differ only by // constant multiples at each bit position have a bounded // number of collisions (approximately 8 at default load factor). h ^= (h >>> 20) ^ (h >>> 12); return h ^ (h >>> 7) ^ (h >>> 4); }
3.放入键值对
代码如下:
public V put(K key, V value) { if (table == EMPTY_TABLE) { inflateTable(threshold); } if (key == null) return putForNullKey(value); int hash = hash(key); 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; }
当我们放入键值对的时候,先判断空间是不是为空,如果为空,则申请一段空间,否则判断键是不是为空,如果为空,则存储空键的值。从代码中,我们可以发现HasMap运行存储空键的值。存储方法如下:
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; }
3.删除操作
final Entry<K,V> removeEntryForKey(Object key) { if (size == 0) { return null; } int hash = (key == null) ? 0 : hash(key); int i = indexFor(hash, table.length); Entry<K,V> prev = table[i]; Entry<K,V> e = prev; while (e != null) { Entry<K,V> next = e.next; Object k; if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) { modCount++; size--; if (prev == e) table[i] = next; else prev.next = next; e.recordRemoval(this); return e; } prev = e; e = next; } return e; }
4.HashMap值存储的数据结构
static class Entry<K,V> implements Map.Entry<K,V> { final K key; V value; Entry<K,V> next; int hash; /** * Creates new entry. */ Entry(int h, K k, V v, Entry<K,V> n) { value = v; next = n; key = k; hash = h; } public final K getKey() { return key; } public final V getValue() { return value; } public final V setValue(V newValue) { V oldValue = value; value = newValue; return oldValue; } public final boolean equals(Object o) { if (!(o instanceof Map.Entry)) return false; Map.Entry e = (Map.Entry)o; Object k1 = getKey(); Object k2 = e.getKey(); if (k1 == k2 || (k1 != null && k1.equals(k2))) { Object v1 = getValue(); Object v2 = e.getValue(); if (v1 == v2 || (v1 != null && v1.equals(v2))) return true; } return false; } public final int hashCode() { return Objects.hashCode(getKey()) ^ Objects.hashCode(getValue()); } public final String toString() { return getKey() + "=" + getValue(); } /** * This method is invoked whenever the value in an entry is * overwritten by an invocation of put(k,v) for a key k that's already * in the HashMap. */ void recordAccess(HashMap<K,V> m) { } /** * This method is invoked whenever the entry is * removed from the table. */ void recordRemoval(HashMap<K,V> m) { } }
0 0
- hashmap 源码阅读
- HashMap源码阅读
- HashMap源码阅读
- HashMap源码阅读
- HashMap源码阅读笔记
- HashMap源码阅读
- Java源码阅读-HashMap
- HashMap源码阅读
- HashMap源码阅读
- HashMap源码阅读
- HashMap源码阅读笔记
- HashMap 1.7源码阅读
- 阅读HashMap源码
- HASHMAP源码阅读分析
- Java源码阅读-HashMap
- HashMap源码阅读
- Jdk8 HashMap源码阅读
- HashMap源码阅读笔记
- 兔子问题
- 记:由opencv中的waitkey引发的一场血案
- 李航统计学习方法笔记1 统计学习方法概论
- iOS常用加密算法和比较
- Word如何转换成PDF格式
- HashMap源码阅读
- 字节序测试函数
- 实现监听输入框字符的变化
- 在Action中Excel导出
- iOS开发--app是怎样运行的
- Android ORMLite 框架的入门用法
- IOS 集合视图指南4:使用流布局
- Android 上实现IOS7风格的Switch
- 互联网我来了 -- 2. js中"异步/阻塞"等概念的简析