JVM里面hashtable和hashmap实现原理

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

JVM里面hashtable和hashmap实现原理

文章分类:java编程转载

在hashtable和hashmap是java里面常见的容器类,

是Java.uitl包下面的类,

那么Hashtable和Hashmap是怎么实现hash键值对配对的呢,我们看看jdk里面的源码,分析下Hashtable的构造方法,put(K, V)加入方法和get(Object)方法就大概明白了。

一、Hashtable的构造方法:Hashtable(int initialCapacity, float loadFactor)

public Hashtable(int initialCapacity, float loadFactor) {

if (initialCapacity < 0)

throw new IllegalArgumentException("Illegal Capacity: "+

initialCapacity);

if (loadFactor <= 0 || Float.isNaN(loadFactor))

throw new IllegalArgumentException("Illegal Load: "+loadFactor);

if (initialCapacity==0)

initialCapacity = 1;

this.loadFactor = loadFactor;

table = new Entry[initialCapacity];

threshold = (int)(initialCapacity * loadFactor);

}

这个里面米内有什么好说的,要注意的是table一个是实体数组,输入的initialCapacity表示这个数组的大小,而threshold 是一个int值,其中loadFactor默认是0.75,就是说明,当table里面的值到75%的阀值后,快要填满数组了,就会自动双倍扩大数字容 量。

而Entry<K,V> 来自与

PRivate static class Entry<K,V> implements Map.Entry<K,V> {

int hash;

K key;

V value;

Entry<K,V> next;

是一个单项链表,

上图就是Hashtable的表,

二、put(K, V)加入方法

public synchronized V put(K key, V value) {

// Make sure the value is not null

if (value == null) {

throw new NullPointerException();

}

// Makes sure the key is not already in the hashtable.

Entry tab[] = table;

int hash = key.hashCode();

int index = (hash & 0x7FFFFFFF) % tab.length;

for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {

if ((e.hash == hash) && e.key.equals(key)) {

V ld = e.value;

e.value = value;

return old;

}

}

modCount++;

if (count >= threshold) {

// Rehash the table if the threshold is exceeded

rehash();

tab = table;

index = (hash & 0x7FFFFFFF) % tab.length;

}

// Creates the new entry.

Entry<K,V> e = tab[index];

tab[index] = new Entry<K,V>(hash, key, value, e);

count++;

return null;

}

这个看看起来很长,只要注意三点就可以了,

1.index,index是键值的hashcode和0x7FFFFFFF的&运算,然后根据数组长度求余值。这样可以定出所在队列名称,

2、

for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {

if ((e.hash == hash) && e.key.equals(key)) {

V ld = e.value;

e.value = value;

return old;

}

}

for语句里面是让e在tab某个队列名为index单项链表里面遍历,第几个单项链表的定义由index定义,看看该队列是否已经有同样的值,如果有,就返回该值。

3、如果没有,则加入

Entry<K,V> e = tab[index];

tab[index] = new Entry<K,V>(hash, key, value, e);

三、get(Object),获得

public synchronized V get(Object key) {

Entry tab[] = table;

int hash = key.hashCode();

int index = (hash & 0x7FFFFFFF) % tab.length;

for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {

if ((e.hash == hash) && e.key.equals(key)) {

return e.value;

}

}

return null;

}

这个就很好理解了 int index = (hash & 0x7FFFFFFF) % tab.length;

获得队列名称,

for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {

if ((e.hash == hash) && e.key.equals(key)) {

return e.value;

}

}

在该队里面遍历,根据hash值获得具体值。

总结下,一个是根据index确定队列,在由hash值获得具体元素值。

看完了hashtable, 我们在来看看hashMap

hashMap可以算作是hashtable的升级版本, 最早从1.2开始有的.

但是, 两者之间最主要的不同有两点.

1. hashMap的读写是unsynchronized, 在多线程的环境中要注意使用

而hashtable是synchronized

这两者的不同是通过在读写方法上加synchronized关键字来实现的.

第二个不同是hashMap可以放空值, 而hashtable就会报错.

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航