Java Hashtable
外观
Java Hashtable[编辑 | 编辑源代码]
Java Hashtable是Java集合框架中一个古老的键值对存储实现,自JDK 1.0起存在。它实现了
Map
接口,使用哈希表数据结构存储数据,具有线程安全的特性(所有方法用
synchronized
修饰)。本章将详细解析其实现原理、使用场景及与现代替代品的对比。
核心特性[编辑 | 编辑源代码]
- 线程安全:所有公共方法均为同步方法
- 不允许键/值:尝试存入
null
会抛出null
NullPointerException
- 初始容量与负载因子:默认初始容量11,负载因子0.75
- 枚举遍历:提供和
elements()
方法返回枚举器keys()
- 继承体系:
基础用法[编辑 | 编辑源代码]
创建实例[编辑 | 编辑源代码]
// 基础构造
Hashtable<String, Integer> populations = new Hashtable<>();
// 指定初始容量
Hashtable<String, Double> prices = new Hashtable<>(20);
// 指定初始容量和负载因子
Hashtable<Character, Boolean> flags = new Hashtable<>(10, 0.5f);
基本操作示例[编辑 | 编辑源代码]
Hashtable<String, Integer> inventory = new Hashtable<>();
inventory.put("Laptop", 15); // 添加
inventory.put("Mouse", 42);
int count = inventory.get("Laptop"); // 获取
inventory.remove("Mouse"); // 删除
boolean exists = inventory.containsKey("Keyboard"); // 检查
并发特性分析[编辑 | 编辑源代码]
由于所有方法都使用
synchronized
修饰,Hashtable可实现线程安全,但会带来性能开销。以下示例演示多线程环境下的安全操作:
class InventoryManager {
private static Hashtable<String, Integer> stock = new Hashtable<>();
public static void updateStock(String item, int delta) {
synchronized(stock) {
stock.put(item, stock.getOrDefault(item, 0) + delta);
}
}
}
页面模块:Message box/ambox.css没有内容。
虽然Hashtable本身线程安全,但复合操作(如"检查再写入")仍需额外同步 |
性能考量[编辑 | 编辑源代码]
哈希表性能受以下因素影响: 平均时间复杂度(理想情况下),但可能退化为(所有键哈希冲突时)
扩容机制[编辑 | 编辑源代码]
当元素数量超过阈值(容量×负载因子)时自动扩容:
与现代集合对比[编辑 | 编辑源代码]
特性 | Hashtable | HashMap | ConcurrentHashMap |
---|---|---|---|
是 | 否 | 是 | |||
否 | 是 | 否 | |||
强一致性 | 快速失败 | 弱一致性 | |||
表级锁 | 无锁 | 分段锁/桶锁 |
实际应用案例[编辑 | 编辑源代码]
配置文件解析[编辑 | 编辑源代码]
Hashtable<String, String> parseConfig(InputStream in) throws IOException {
Properties props = new Properties();
props.load(in); // Properties继承Hashtable
return new Hashtable<>(props);
}
数据缓存实现[编辑 | 编辑源代码]
class SimpleCache<K,V> {
private final Hashtable<K,V> cache = new Hashtable<>();
private final int maxSize;
public synchronized void put(K key, V value) {
if(cache.size() >= maxSize) {
cache.clear();
}
cache.put(key, value);
}
}
高级技巧[编辑 | 编辑源代码]
自定义哈希函数[编辑 | 编辑源代码]
重写键对象的
hashCode()
和
equals()
方法:
class Product {
String id;
String category;
@Override
public int hashCode() {
return Objects.hash(id, category);
}
@Override
public boolean equals(Object o) {
// 实现细节省略
}
}
同步视图创建[编辑 | 编辑源代码]
Map<String, Integer> syncMap = Collections.synchronizedMap(new HashMap<>());
// 与Hashtable类似但允许null值
常见问题[编辑 | 编辑源代码]
最佳实践[编辑 | 编辑源代码]
- 新代码优先考虑
ConcurrentHashMap
- 需要序列化时实现/
readObject
方法控制过程writeObject
- 遍历大型Hashtable时使用而非
entrySet()
提高效率keySet()
- 预估数据量时设置合理的初始容量避免频繁rehash
参考代码[编辑 | 编辑源代码]
完整线程安全示例:
class TransactionManager {
private final Hashtable<Long, Transaction> activeTransactions
= new Hashtable<>(1000);
public void beginTransaction(Long txId, Transaction tx) {
activeTransactions.put(txId, tx);
}
public void commit(Long txId) {
Transaction tx = activeTransactions.remove(txId);
if(tx != null) {
tx.commit();
}
}
public synchronized Collection<Transaction> getPendingTransactions() {
return new ArrayList<>(activeTransactions.values());
}
}