HashMap与HashTable的区别

链接:https://www.nowcoder.com/questionTerminal/687a87f9018e4ba4a747ff31ffbcd9c9?toCommentId=1771794
来源:牛客网

看看继承体系
然后HashMap可以允许Null做键或者值,但是Null的键 只能有一个

这个表上的知识能够让你明白个体系,但是具体我们看看HashMap的码源吧
1.都实现了map接口
public class HashMap<K,V>
    extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable
public class Hashtable<K,V>
    extends Dictionary<K,V>
    implements Map<K,V>, Cloneable, java.io.Serializable
2.Hashtable的主要方法都是同步方法
 public synchronized V put(K key, V value) 
 public synchronized V get(Object key)
所以Hashtable是线程安全的
HashMap的主要方法
public V put(K key, V value)
public V get(Object key)
3.是否允许控制这个问题看看码源
Hashtable中不允许空值存在
 if (value == null) {
            throw new NullPointerException();
   }
然而HashMap通过码源检查发现
 if (key == null)
            return putForNullKey(value);
允许null作为键或者值
由于key-value形式,所以只能有一个Null的key
4.关于hash值的问题
HashMap将hash值重新计算是一个
 final int hash(Object k) {
        int h = hashSeed;
        if (0 != h && k instanceof String) {
            return sun.misc.Hashing.stringHash32((String) k);
        }

        h ^= k.hashCode();

        // This function ensures that hashCodes that differ only by
        // constant multiples at each bit position have a bounded
        // number of collisions (approximately 8 at default load factor).
        h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h >>> 4);
    }
这样的方法,进行哈希运算,新的hash值
而Hashtable采取的是
 int hash = key.hashCode();的方式进行计算
5.关于扩容问题HashMap采取直接扩大两倍,初始长度16
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
 public HashMap(Map<? extends K, ? extends V> m) {
        this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1,
                      DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR);
        inflateTable(threshold);

        putAllForCreate(m);
    }

 if ((size >= threshold) && (null != table[bucketIndex])) {
            resize(2 * table.length);
            hash = (null != key) ? hash(key) : 0;
            bucketIndex = indexFor(hash, table.length);
        }
而HashTable的策略是乘以2增长,初始11
public Hashtable(Map<? extends K, ? extends V> t) {
        this(Math.max(2*t.size(), 11), 0.75f);
        putAll(t);
    }

 
posted @   coder-zhou  阅读(329)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
点击右上角即可分享
微信分享提示