架构师之面试------jdk的hashMap实现

1.前言。
  如题。
2.详述。
  (1)hashMap算法就是数组链表。数组存放的元素是键值对。jdk通过移位算法(其实也就是简单的加乘算法),如下代码来生成数组下标(生成后indexFor一下就成下标了)。
static int hash(int h) 
{ 
    h ^= (h >>> 20) ^ (h >>> 12); 
    return h ^ (h >>> 7) ^ (h >>> 4); 
}

(2)hashMap的键值对存放的位置和key的值无必然联系,是通过简单的与操作来获得数组下标的。
如:
static int indexFor(int h, int length) 
{ 
    return h & (length-1); 
}

(3)hashmap的负载因子默认是0.75, 增大和减少无任何意义,jdk对于这个东西的介绍已经很过时了。超过0.75就变为两倍的容量, 自动扩容无任何意义,因为存储的数据大小是受磁盘和内存限制的。通常是程序自动限制个上限就可以了。

3.一句话概括jdk的hashmap实现
  就是一个数组加链表,数组里面存放键值对的链表(链表里面放Entry),一般链表只有一个key的元素。如果有key一样的情况,那么put会将其添加到链表里面,此时链表有多个值。
如:
public V put(K key, V value) 
 { 
	 // 如果 key 为 null,调用 putForNullKey 方法进行处理
	 if (key == null) 
		 return putForNullKey(value); 
	 // 根据 key 的 keyCode 计算 Hash 值
	 int hash = hash(key.hashCode()); 
	 // 搜索指定 hash 值在对应 table 中的索引
 	 int i = indexFor(hash, table.length);
	 // 如果 i 索引处的 Entry 不为 null,通过循环不断遍历 e 元素的下一个元素
	 for (Entry<K,V> e = table[i]; e != null; e = e.next) 
	 { 
		 Object k; 
		 // 找到指定 key 与需要放入的 key 相等(hash 值相同
		 // 通过 equals 比较放回 true)
		 if (e.hash == hash && ((k = e.key) == key 
			 || key.equals(k))) 
		 { 
			 V oldValue = e.value; 
			 e.value = value; 
			 e.recordAccess(this); 
			 return oldValue; 
		 } 
	 } 
	 // 如果 i 索引处的 Entry 为 null,表明此处还没有 Entry 
	 modCount++; 
	 // 将 key、value 添加到 i 索引处
	 addEntry(hash, key, value, i); 
	 return null; 
 }

4.注意事项。
   hashmap不能避免hash冲突,只是简单校验,所以经常要重写对象的equals方法。 hashmap可能会淘汰,应该有唯一性算法替代hash算法(如hadoop自定义的序列,我自己也可以开发对应的序列,大数据情况下散列不再重要),算法效率当今已经不是个问题。

你可能感兴趣的:(HashMap)