Hashtable源码

Hashtable简介

Hashtable基于哈希表实现的,每个元素都是key-value对,通过单链表解决哈希冲突。
Hashtable是线程安全的,实现Serializable可以序列化,实现Cloneable接口,能被克隆。

源码

package java.util;

import java.io.*;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.BiFunction;
import jdk.internal.access.SharedSecrets;

public class Hashtable<K,V>
    extends Dictionary<K,V>
    implements Map<K,V>, Cloneable, java.io.Serializable {
    
    // 保存key-value对的数组
    private transient Entry<?,?>[] table;

	// key-value的数量
    private transient int count;

	// 超过这个值就扩容(threshold=容量*loadfactor)
    private int threshold;

	// 加载因子 默认0.75根hashMap一样
    private float loadFactor;

	// 被改变的次数
    private transient int modCount = 0;

	// 序列版本号
    private static final long serialVersionUID = 1421746759512286392L;

	// 指定容量大小和加载因子的构造函数
    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);
    }

	// 默认构造函数
	// 容量默认为11 加载因子默认为0.75f
    public Hashtable() {
        this(11, 0.75f);
    }

	// 复制map
    public Hashtable(Map<? extends K, ? extends V> t) {
        this(Math.max(2*t.size(), 11), 0.75f); // 构造
        putAll(t); //全部元素添加过来
    }

    Hashtable(Void dummy) {}

	// key-value的数量
    public synchronized int size() {
        return count;
    }

	// 为空
    public synchronized boolean isEmpty() {
        return count == 0;
    }

	// 返回key的枚举对象
    public synchronized Enumeration<K> keys() {
        return this.<K>getEnumeration(KEYS);
    }

	// 返回value的枚举对象
    public synchronized Enumeration<V> elements() {
        return this.<V>getEnumeration(VALUES);
    }

	// 判断Hashtable所有key-value中value是否包含 这个value
    public synchronized boolean contains(Object value) {
    	// 如果value为null就抛出异常
        if (value == null) {
            throw new NullPointerException();
        }
		
		// 从后往前遍历所有key-value
        Entry<?,?> tab[] = table;
        for (int i = tab.length ; i-- > 0 ;) {
        	// Entry为单链表,循环遍历,判断当前节点是否为value
            for (Entry<?,?> e = tab[i] ; e != null ; e = e.next) {
                if (e.value.equals(value)) {
                    return true;
                }
            }
        }
        return false;
    }

    public boolean containsValue(Object value) {
        return contains(value);
    }

	// 判断key-value对中是否存在这样一个key
    public synchronized boolean containsKey(Object key) {
        Entry<?,?> tab[] = table;
        // 计算key的hash值
        int hash = key.hashCode();
        // 算出在table中的位置
        int index = (hash & 0x7FFFFFFF) % tab.length;
        // 取出该位置的Entry(单链表)hash值和key值都相等的元素是否存在
        for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) {
            if ((e.hash == hash) && e.key.equals(key)) {
                return true;
            }
        }
        return false;
    }

	// 根据key找出value,没有返回null
    @SuppressWarnings("unchecked")
    public synchronized V get(Object key) {
        Entry<?,?> tab[] = table;
        int hash = key.hashCode();
        // 计算下标
        int index = (hash & 0x7FFFFFFF) % tab.length;
        // 在这个key所对应的链表中找出一个hash值和key值都相等的元素
        for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) {
            if ((e.hash == hash) && e.key.equals(key)) {
                return (V)e.value;
            }
        }
        return null;
    }

    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

	// Hashtable的扩容
    @SuppressWarnings("unchecked")
    protected void rehash() {
        int oldCapacity = table.length;
        Entry<?,?>[] oldMap = table;
			
        // 扩容为原来的2倍+1
        int newCapacity = (oldCapacity << 1) + 1;
        if (newCapacity - MAX_ARRAY_SIZE > 0) {
            if (oldCapacity == MAX_ARRAY_SIZE)
                // Keep running with MAX_ARRAY_SIZE buckets
                return;
            newCapacity = MAX_ARRAY_SIZE;
        }
        // 创建新容量大小的table
        Entry<?,?>[] newMap = new Entry<?,?>[newCapacity];

        modCount++;
        // 阀值更新
        threshold = (int)Math.min(newCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
        table = newMap;
		
		// 将旧的复制到新的
        for (int i = oldCapacity ; i-- > 0 ;) {
            for (Entry<K,V> old = (Entry<K,V>)oldMap[i] ; old != null ; ) {
                Entry<K,V> e = old;
                old = old.next;
				重新计算index
                int index = (e.hash & 0x7FFFFFFF) % newCapacity;
                e.next = (Entry<K,V>)newMap[index];
                newMap[index] = e;
            }
        }
    }

	// 在index处插入key-value
    private void addEntry(int hash, K key, V value, int index) {
        Entry<?,?> tab[] = table;
        // 超过阀值要扩容
        if (count >= threshold) {
            // Rehash the table if the threshold is exceeded
            rehash();

            tab = table;
            hash = key.hashCode(); // 重新计算hash值
            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); // 将新的节点插入到tab[index]处链的头部
        count++;
        modCount++;
    }

	// 添加元素
    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(); // 计算hash值
        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)) { // 如果存在一个hash值和key值都相等的元素就更换value,返回旧的value
                V old = entry.value;
                entry.value = value;
                return old;
            }
        }
		// 添加
        addEntry(hash, key, value, index);
        return null;
    }

	// 删除key值为key的key-value
    public synchronized V remove(Object key) {
        Entry<?,?> tab[] = table;
        int hash = key.hashCode();
        int index = (hash & 0x7FFFFFFF) % tab.length;
        @SuppressWarnings("unchecked")
        Entry<K,V> e = (Entry<K,V>)tab[index]; // 找到所在链的所处下标,取出链
        for(Entry<K,V> prev = null ; e != null ; prev = e, e = e.next) { 
            if ((e.hash == hash) && e.key.equals(key)) { // 找到删除节点
                if (prev != null) { // e为待删节点,prev为e的上一节点
                    prev.next = e.next; // prev的下一节点指向e的下一节点,e节点丢失
                } else {
                    tab[index] = e.next;
                }
                modCount++;
                count--;
                V oldValue = e.value;
                e.value = null;
                return oldValue;
            }
        }
        return null;
    }

	// 将map的元素一个一个添加到Hashtable里面
    public synchronized void putAll(Map<? extends K, ? extends V> t) {
        for (Map.Entry<? extends K, ? extends V> e : t.entrySet())
            put(e.getKey(), e.getValue());
    }

	// 清空Hashtable,全部设为null
    public synchronized void clear() {
        Entry<?,?> tab[] = table;
        for (int index = tab.length; --index >= 0; )
            tab[index] = null;
        modCount++;
        count = 0;
    }

	// 克隆一个Hashtable
    public synchronized Object clone() {
        Hashtable<?,?> t = cloneHashtable();
        t.table = new Entry<?,?>[table.length];
        for (int i = table.length ; i-- > 0 ; ) {
            t.table[i] = (table[i] != null)
                ? (Entry<?,?>) table[i].clone() : null;
        }
        t.keySet = null;
        t.entrySet = null;
        t.values = null;
        t.modCount = 0;
        return t;
    }

    /** Calls super.clone() */
    final Hashtable<?,?> cloneHashtable() {
        try {
            return (Hashtable<?,?>)super.clone();
        } catch (CloneNotSupportedException e) {
            // this shouldn't happen, since we are Cloneable
            throw new InternalError(e);
        }
    }

    public synchronized String toString() {
        int max = size() - 1;
        if (max == -1)
            return "{}";

        StringBuilder sb = new StringBuilder();
        Iterator<Map.Entry<K,V>> it = entrySet().iterator();

        sb.append('{');
        for (int i = 0; ; i++) {
            Map.Entry<K,V> e = it.next();
            K key = e.getKey();
            V value = e.getValue();
            sb.append(key   == this ? "(this Map)" : key.toString());
            sb.append('=');
            sb.append(value == this ? "(this Map)" : value.toString());

            if (i == max)
                return sb.append('}').toString();
            sb.append(", ");
        }
    }

	// 获取Hashtable的枚举类对象
    private <T> Enumeration<T> getEnumeration(int type) {
        if (count == 0) { // 如果Hashtable为空则返回一个空枚举类对象
            return Collections.emptyEnumeration();
        } else { // 返回正常的Enumerator对象
            return new Enumerator<>(type, false);
        }
    }

	// 获取Hashtable的迭代器
    private <T> Iterator<T> getIterator(int type) {
        if (count == 0) { // 为空返回空迭代器对象
            return Collections.emptyIterator();
        } else { // 返回Enumerator对象
            return new Enumerator<>(type, true);
        }
    }

	// key的set集合,没有重复元素
    private transient volatile Set<K> keySet;
    // key-value集合
    private transient volatile Set<Map.Entry<K,V>> entrySet;
    // value的Collection集合, 允许重复
    private transient volatile Collection<V> values;

	// 返回一个keySet对象,多线程同步,因为被synchronizedSet封装keySet的所有方法都添加了synchronized关键字
    public Set<K> keySet() {
        if (keySet == null)
            keySet = Collections.synchronizedSet(new KeySet(), this);
        return keySet;
    }
	
	// key的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();
        }
    }

	// 返回一个EntrySet对象
    public Set<Map.Entry<K,V>> entrySet() {
        if (entrySet==null)
            entrySet = Collections.synchronizedSet(new EntrySet(), this);
        return entrySet;
    }

	// Entry的set集合,没有重复元素
    private class EntrySet extends AbstractSet<Map.Entry<K,V>> {
        public Iterator<Map.Entry<K,V>> iterator() {
            return getIterator(ENTRIES);
        }

        public boolean add(Map.Entry<K,V> o) {
            return super.add(o);
        }
		
		// 查找Entry中是否包含o,在table中找到o所对应的entry链表,在判断链中是否存有o
        public boolean contains(Object o) {
            if (!(o instanceof Map.Entry))
                return false;
            Map.Entry<?,?> entry = (Map.Entry<?,?>)o;
            Object key = entry.getKey();
            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.equals(entry))
                    return true;
            return false;
        }

		// 删除o,在table中找到o所对应的entry链表,删除链中的o节点
        public boolean remove(Object o) {
            if (!(o instanceof Map.Entry))
                return false;
            Map.Entry<?,?> entry = (Map.Entry<?,?>) o;
            Object key = entry.getKey();
            Entry<?,?>[] tab = table;
            int hash = key.hashCode();
            int index = (hash & 0x7FFFFFFF) % tab.length;

            @SuppressWarnings("unchecked")
            Entry<K,V> e = (Entry<K,V>)tab[index];
            for(Entry<K,V> prev = null; e != null; prev = e, e = e.next) {
                if (e.hash==hash && e.equals(entry)) {
                    if (prev != null)
                        prev.next = e.next;
                    else
                        tab[index] = e.next;

                    e.value = null; // clear for gc.
                    modCount++;
                    count--;
                    return true;
                }
            }
            return false;
        }

        public int size() {
            return count;
        }

        public void clear() {
            Hashtable.this.clear();
        }
    }

	// 返回ValueCollection对象,多线程同步
    public Collection<V> values() {
        if (values==null)
            values = Collections.synchronizedCollection(new ValueCollection(),
                                                        this);
        return values;
    }

	// value的Collection集合
    private class ValueCollection extends AbstractCollection<V> {
        public Iterator<V> iterator() {
            return getIterator(VALUES);
        }
        public int size() {
            return count;
        }
        public boolean contains(Object o) {
            return containsValue(o);
        }
        public void clear() {
            Hashtable.this.clear();
        }
    }

	// 重写equals方法如果两个Hashtable的所有key-value都相等就判断他们俩相等
    public synchronized boolean equals(Object o) {
        if (o == this)
            return true;

        if (!(o instanceof Map))
            return false;
        Map<?,?> t = (Map<?,?>) o;
        if (t.size() != size())
            return false;

        try {
            for (Map.Entry<K, V> e : entrySet()) {
                K key = e.getKey();
                V value = e.getValue();
                if (value == null) {
                    if (!(t.get(key) == null && t.containsKey(key)))
                        return false;
                } else {
                    if (!value.equals(t.get(key)))
                        return false;
                }
            }
        } catch (ClassCastException unused)   {
            return false;
        } catch (NullPointerException unused) {
            return false;
        }

        return true;
    }

	// 计算entry的hashCode、
    public synchronized int hashCode() {
     
        int h = 0;
        // 如果没有key-value或者加载因子小与0,那么hashCode为0
        
        if (count == 0 || loadFactor < 0)
            return h;  // Returns zero

        loadFactor = -loadFactor;  // Mark hashCode computation in progress
        Entry<?,?>[] tab = table;
        for (Entry<?,?> entry : tab) {
            while (entry != null) {
                h += entry.hashCode();
                entry = entry.next;
            }
        }

        loadFactor = -loadFactor;  // Mark hashCode computation complete

        return h;
    }

	// 如果key所对应的value为null那么就返回defaultValue否则返回value
    @Override
    public synchronized V getOrDefault(Object key, V defaultValue) {
        V result = get(key);
        return (null == result) ? defaultValue : result;
    }

   
}

Hashtable相比HashMap

  1. 存储结构都是一样的。解决hash冲突的方式也是一样的
  2. Hashtable默认容量大小为11,HashMap默认大小为16,Hashtable没有强调底层数组必须为2的n次方,而HashMap要求必须为2的幂
  3. Hashtable要求key和value不能为null,HashMap则是key,value都可以为null。
  4. Hashtable扩容为容量扩大为原来2倍+1,HashMap为原来的2倍。
  5. Hashtable计算hash值,直接使用key的hashCode,Hashmap则是重新计算hash值。
  6. 计算当前元素应该所处数组下标,Hashtable用的%运算,而HashMap用的是与运算。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值