Jdk源码分析

文章40 |   阅读 10201 |   点赞0

来源:https://yumbo.blog.csdn.net/category_10384063.html

HashTable源码解读

x33g5p2x  于2021-12-18 转载在 其他  
字(2.1k)|赞(0)|评价(0)|浏览(284)

面试过程中HashTable是一个常考的知识点
常常会将HashMap 或 ConcurrentHashMap进行比较。

今天特意看了一下 HashTable源码
总结了几个常考知识点

一、初始容量11,最大容量为 231-8

HashMap和ConcurrentHashMap默认初始容量是16。而HashTable是11
默认的扩容因子都是0.75,也都是2倍的方式进行扩容
下面是它的构造方法如下

// 最大容量
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
// 默认空参构造,创建时初始容量是11,而HashMap和ConcurrentHashMap默认初始容量是16
public Hashtable() {
    this(11, 0.75f);
}

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)Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
}

public Hashtable(int initialCapacity) {
    this(initialCapacity, 0.75f);
}

public Hashtable(Map<? extends K, ? extends V> t) {
    this(Math.max(2*t.size(), 11), 0.75f);
    putAll(t);
}
二、线程安全问题

HashTable和ConcurrentHashMap都是线程安全的,而HashMap是线程不安全的
原因在于HashTable的增删改查都加了synchronized
会看下下面一排的synchronized关键字

三、为什么说HashTable的key和value都不能为null

贴出源码,很容易就明白了,已put方法为例
会发现value==null时就会抛出一个空指针异常
key=null呢?会发现int hash = key.hashCode()很明显如果key为null也会抛一个空指针异常。
故HashTable的Key和value都不可以为null

public synchronized V put(K key, V value) {
    if (value == null) {
        throw new NullPointerException();
    }
    Entry<?,?> tab[] = table;
    int hash = key.hashCode();
    int index = (hash & 0x7FFFFFFF) % tab.length;
    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;
}
扩展:HashMap的key和value可否为空?

HashMap可以,为什么呢?
下面是HashMap的put方法,会发现HashMap调用的是自己内部的hash方法,
如果key为null则会返回hash值 0
而value会被存进Node结点的value中。不会像HashTable对值进行校验

public V put(K key, V value) {
    return putVal(hash(key), key, value, false, true);
}
static final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

在HashMap中可能会调用value.equals方法的代码如下,会发现前面做了校验空处理
value.equals

其它

增删改查元素和HashMap相同。
自行解读或者
参考:
HashMap常见面试题和源码注释

相关文章