java.util.HashMap源码初探
2013-03-30 16:38
471 查看
对于一个存储类的分析,无非从两点入手:存储用的数据结构,存储的运行机制。
数据结构:
数组
Entry
链表格式。
也即,HashMap中采用的是“链接法”来处理碰撞问题的。
运行机制:
put、get
put方法
get方法
可以看出,重要的一句代码为:
这句代码的作用是判断两个Key对象是否“相同”,这里的相同的意思是指两个Key完全可以不分彼此,可以作为同一个Key使用。
在put方法中,如果两个Key的hashCode相同,且equals符合,这里是把原有的的value替换成新的value。
测试代码:
数据结构:
数组
/** * The table, resized as necessary. Length MUST Always be a power of two. */ transient Entry[] table;
Entry
链表格式。
也即,HashMap中采用的是“链接法”来处理碰撞问题的。
运行机制:
put、get
put方法
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; }
get方法
public V get(Object key) { if (key == null) return getForNullKey(); int hash = hash(key.hashCode()); 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; }
可以看出,重要的一句代码为:
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
这句代码的作用是判断两个Key对象是否“相同”,这里的相同的意思是指两个Key完全可以不分彼此,可以作为同一个Key使用。
在put方法中,如果两个Key的hashCode相同,且equals符合,这里是把原有的的value替换成新的value。
测试代码:
package test.junit; import java.util.HashMap; import junit.framework.TestCase; /** * HashMap中判断两个Key是否相同:先判断hashCode,在判断是否equals * e.hash == hash && ((k = e.key) == key || key.equals(k)) * @author xuefeng * */ public class HashMapTest extends TestCase { /** * v1和v4的hashCode相同,但是equals不符合,所以v1和v4会组成一个链表。 */ public void testKey1() { HashMap<Key, Value> map = new HashMap<Key, Value>(); Key k1 = new Key(1); Key k4 = new Key(4); Value v1 = new Value(1); Value v4 = new Value(4); map.put(k1, v1); map.put(k4, v4); assertEquals(v1, map.get(k1)); assertEquals(v4, map.get(k4)); } /** * v1和v4的hashCode相同,而且equals也符合,所以v1会被v4替换掉,k1和k4指向同一个v4。 */ public void testKey2() { HashMap<Key2, Value> map = new HashMap<Key2, Value>(); Key2 k1 = new Key2(1); Key2 k4 = new Key2(4); Value v1 = new Value(1); Value v4 = new Value(4); map.put(k1, v1); map.put(k4, v4); // 这里会替换掉v1 // assertEquals(v1, map.get(k1)); assertEquals(v4, map.get(k1)); assertEquals(v4, map.get(k4)); } } class Key { public int m; public Key(int m) { this.m = m; } @Override public int hashCode() { return m%3; } } class Value { public int m; public Value(int m) { this.m = m; } } class Key2 { public int m; public Key2(int m) { this.m = m; } @Override public int hashCode() { return m%3; } @Override public boolean equals(Object obj) { if(obj == null || !(obj instanceof Key2)) return false; Key2 other = (Key2)obj; return this.hashCode() == other.hashCode(); } }
相关文章推荐
- java.util.HashMap源码初探
- java.util.LinkedHashMap源码解析
- java.util.HashMap源码要点浅析
- java.util.concurrent.ConcurrentHashMap并发哈希表源码解析
- JDK源码学习(4)-java.util.HashMap、LinkedHashMap与TreeMap
- JDK1.8源码(三)——java.util.HashMap
- 散列表:java.util.HashMap源码要点浅析
- Java java.util.HashMap实现原理源码分析
- JAVA 集合类(java.util)源码阅读笔记------HashMap
- Java中hashMap的源码初探
- java.util.HashMap源码解析
- java.util.concurrent 之ConcurrentHashMap 源码分析
- Java 1.8 HashMap源码探究
- 初探Java源码之LinkedList
- 从源码分析java集合【HashMap】
- Java集合---HashMap源码剖析
- Java集合HashMap源码剖析
- java集合10--HashMap源码走读
- Java容器_Map_HashMap源码分析
- java核心之集合框架——HashMap源码分析