您的位置:首页 > 编程语言 > Java开发

jdk 源码分析(2)java hashtable的结构及hashMap对比

2017-08-01 23:33 966 查看
1)首先hashtable 只有一种存储结构。线性链表,这和hashmap 不同,hashmap 当数据量大是采用二叉树,可以加快查询。

/**

* Hashtable bucket collision list entry

*/

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

final int hash;

final K key;

V value;

Entry<K,V> next;


protected Entry(int hash, K key, V value, Entry<K,V> next) {

this.hash = hash;

this.key =  key;

this.value = value;

this.next = next;

}


2)对比put,hashtable 是线程安全的,但是valeu都不能为空,而hashmap可以的

 //同步代码块,线程安全

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

// Make sure the value is not null

if (value == null) {  //value 不能为空

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;

@SuppressWarnings("unchecked")

Entry<K,V> entry = (Entry<K,V>)tab[index];

for(; entry != null ; entry = entry.next) {

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

V old = entry.value;

entry.value = value;

return old;

}

}


addEntry(hash, key, value, index);

return null;

}


上面的方法主要是确认里面没有相同的key。
最后调用的addEntry:这是一种头部插入数据方式。头部插入要比hashmap的尾部插入快,没有理解为什么hashmap 不采用头部插入。可能为了统一treeNode的原因吧。

private void addEntry(int hash, K key, V value, int index) {

modCount++;


Entry<?,?> tab[] = table;

if (count >= threshold) {

// Rehash the table if the threshold is exceeded

rehash();


tab = table;

hash = key.hashCode();

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

}


// Creates the new entry.

@SuppressWarnings("unchecked")

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

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

count++;

}


3)get :get 简单,唯一不同就是同步

public synchronized V get(Object key) {
Entry<?,?> tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
return (V)e.value;
}
}
return null;
}


4)keySet() 返回的虽然是一个set集合但是其实本身不存数据,数据还是存放在Hashtable中,包括EntrySet 等,

以前一直以为一个Set ,那么他一定存放数据了,其实错了,Set只是一堆方法。数据哪怕你放在数据库中都行,。

private class KeySet extends AbstractSet<K> {
public Iterator<K> iterator() {
return getIterator(KEYS);
}
public int size() {
return count;
}
public boolean contains(Object o) {
return containsKey(o);
}
public boolean remove(Object o) {
return Hashtable.this.remove(o) != null;
}
public void clear() {
Hashtable.this.clear();
}
}


里面提到的hashmap可以参考:jdk 源码分析(1) hashmap的结构

总结: hashtable线程安全,但是查询速度慢,

其他东西不在分析,可以自己去看一下代码。源代码其实很简单。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  源代码 jdk