您的位置:首页 > 其它

HashMap内部存储实现及HashTable比较

2014-04-26 10:00 239 查看
一、HashMap的内部存储实现

HashMap底层实现的数据结构是哈希表。哈希表的实现一般有两种,第一种是数组(闭散列),第二种是数组+链表(开散列)。而HashMap采用的是“数组+链表”的实现,

即数组存储链表的头结点。

1、HashMap存储数据时进行put( key, value )的操作,源代码如下:

[java] view
plaincopy





public V put(K key, V value) {

if (key == null)

return putForNullKey(value);

int hash = hash(key.hashCode()); //首先进行key.hashCode()操作,获取key的哈希值

int i = indexFor(hash, table.length); //相当于:int i = hash % Entry[].length,Entry.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;

}

注意:在Entry类里面有一个next属性,指向下一个Entry。例如,第一个键值对A进来,通过计算得到其key的hash是1,则存储:Entry[1]=A。接着,第二个键值对B进来,其key的hash也等于1,那么HashMap会这样做:B.next = A, Entry[1] = B,以此类推。由此可知,数组中存储的是最后插入的元素。

2、取出数据进行get( key )操作,源代码如下:

[java] view
plaincopy





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;

}

当key不为空时,先根据hash函数得到hash值,再根据indexFor()得到数组的索引值,接着遍历链表。如果有key值等于已存在的key值,则返回其value。

二、HashMap和HashTable的比较

HashTable和HashMap采用相同的存储机制,二者的实现基本一致,不同的是:

1. HashMap是非线程安全的,HashTable是线程安全的。

2. HashMap的键和值都可以为null,但是HashTable不行。

3. 由于线程安全的关系,HashMap的效率比HashTable要高。

4. HashMap没有使用HashTable的contains()函数,取而代之的是containsKey()和containsValue()。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: