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

1)首先hashtable 只有一种存储结构。线性链表,这和hashmap 不同,hashmap 当数据量大是采用二叉树,可以加快查询。
     
     
  1. /**
  2. * Hashtable bucket collision list entry
  3. */
  4. private static class Entry<K,V> implements Map.Entry<K,V> {
  5. final int hash;
  6. final K key;
  7. V value;
  8. Entry<K,V> next;
  9. protected Entry(int hash, K key, V value, Entry<K,V> next) {
  10. this.hash = hash;
  11. this.key = key;
  12. this.value = value;
  13. this.next = next;
  14. }
2)对比put,hashtable 是线程安全的,但是valeu都不能为空,而hashmap可以的
    
    
  1.  //同步代码块,线程安全
  2. public synchronized V put(K key, V value) {
  3. // Make sure the value is not null
  4. if (value == null) { //value 不能为空
  5. throw new NullPointerException();
  6. }
  7. // Makes sure the key is not already in the hashtable.
  8. Entry<?,?> tab[] = table;
  9. int hash = key.hashCode();
  10. int index = (hash & 0x7FFFFFFF) % tab.length;
  11. @SuppressWarnings("unchecked")
  12. Entry<K,V> entry = (Entry<K,V>)tab[index];
  13. for(; entry != null ; entry = entry.next) {
  14. if ((entry.hash == hash) && entry.key.equals(key)) {
  15. V old = entry.value;
  16. entry.value = value;
  17. return old;
  18. }
  19. }
  20. addEntry(hash, key, value, index);
  21. return null;
  22. }
上面的方法主要是确认里面没有相同的key。
最后调用的addEntry:这是一种头部插入数据方式。头部插入要比hashmap的尾部插入快,没有理解为什么hashmap 不采用头部插入。可能为了统一treeNode的原因吧。
      
      
  1. private void addEntry(int hash, K key, V value, int index) {
  2. modCount++;
  3. Entry<?,?> tab[] = table;
  4. if (count >= threshold) {
  5. // Rehash the table if the threshold is exceeded
  6. rehash();
  7. tab = table;
  8. hash = key.hashCode();
  9. index = (hash & 0x7FFFFFFF) % tab.length;
  10. }
  11. // Creates the new entry.
  12. @SuppressWarnings("unchecked")
  13. Entry<K,V> e = (Entry<K,V>) tab[index];
  14. tab[index] = new Entry<>(hash, key, value, e);
  15. count++;
  16. }


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线程安全,但是查询速度慢,

其他东西不在分析,可以自己去看一下代码。源代码其实很简单。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值