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
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();
}
throw new NullPointerException();
}
然而HashMap通过码源检查发现
if (key == null)
return putForNullKey(value);
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值
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);
}
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);
}
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);
}
this(Math.max(2*t.size(), 11), 0.75f);
putAll(t);
}
恐惧源于无知,代码改变世界
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .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 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义