当前位置: 首页 > article >正文

问:Java中HashMap和Hashtable区别,知多少?

维度HashMapHashtable
父类AbstractMapDictionary
接口实现Map, Cloneable, SerializableMap, Cloneable, Serializable
提供的额外方法elements(), contains()
对null的支持key可以为null(唯一),value可以为nullkey和value都不能为null
线程安全性非线程安全线程安全(方法上有synchronized)
性能高效,非同步开销较低,同步开销
初始容量/扩充容量初始容量16,扩充为2倍初始容量11,扩充为2倍+1
计算hash值方法自定义hash()方法直接使用key的hashCode()

示例

初始化与基本使用
import java.util.HashMap;
import java.util.Hashtable;

public class MapComparison {
    public static void main(String[] args) {
        // HashMap 示例
        HashMap<String, Integer> hashMap = new HashMap<>();
        hashMap.put("One", 1);
        hashMap.put("Two", 2);
        hashMap.put(null, 3); // key可以为null

        System.out.println("HashMap: " + hashMap);

        // Hashtable 示例
        Hashtable<String, Integer> hashtable = new Hashtable<>();
        hashtable.put("One", 1);
        hashtable.put("Two", 2);
        // hashtable.put(null, 3); // 编译错误,key不能为null

        System.out.println("Hashtable: " + hashtable);

        // Hashtable 的 extra 方法
        // 注意:由于这些方法是Hashtable特有的,因此不能在HashMap上调用
        System.out.println("Hashtable elements: " + hashtable.elements()); // 返回Enumeration对象
        // System.out.println("Hashtable contains 1: " + hashtable.contains(1)); // 实际上应该使用containsValue(1)
        System.out.println("Hashtable containsValue 1: " + hashtable.containsValue(1));
    }
}
线程安全性
// 注意:这只是为了说明线程安全性的概念,并不是实际的并发测试代码
public class ThreadSafetyExample {
    // 非线程安全的HashMap
    private static HashMap<Integer, Integer> hashMap = new HashMap<>();

    // 线程安全的Hashtable
    private static Hashtable<Integer, Integer> hashtable = new Hashtable<>();

    public static void main(String[] args) {
        // 对于HashMap,需要额外的同步机制来确保线程安全
        // synchronized (hashMap) {
        //     hashMap.put(1, 1);
        // }

        // Hashtable自带同步机制,无需额外处理
        hashtable.put(1, 1);
    }
}

分析

  1. 父类与接口实现

    • HashMap继承自AbstractMap,而Hashtable继承自Dictionary。尽管它们的父类不同,但两者都实现了MapCloneableSerializable接口。
  2. 提供的额外方法

    • Hashtable提供了elements()contains()两个额外的方法。elements()方法返回一个Enumeration对象,用于遍历Hashtable中的值。contains()方法在Hashtable中实际上与containsValue()方法功能相同,但在HashMap中并不存在该方法。
  3. 对null的支持

    • HashMap允许一个null键和多个null值。Hashtable则不允许键或值为null。
  4. 线程安全性

    • HashMap是非线程安全的,适用于单线程环境。在多线程环境中使用时,需要额外的同步机制来确保线程安全。
    • Hashtable是线程安全的,其所有方法都是同步的,因此可以直接用于多线程环境中。然而,这种同步机制会导致性能下降。
  5. 性能

    • 由于HashMap没有同步开销,因此其性能通常高于Hashtable
  6. 初始容量与扩充容量

    • HashMap的初始容量为16,当容量不足时,会扩充为原来的2倍。
    • Hashtable的初始容量为11,当容量不足时,会扩充为原来的2倍加1(例如,11->23->47)。
  7. 计算hash值的方法

    • HashMap使用自定义的hash()方法来计算键的哈希值,该方法会对键的hashCode()进行进一步处理以减少哈希冲突。
    • Hashtable则直接使用键的hashCode()作为哈希值。

综上所述,HashMapHashtable在多个维度上存在显著差异。对于需要线程安全且性能要求不高的场景,可以选择Hashtable;对于性能要求高且能够自己处理线程安全的场景,则更推荐使用HashMap。如果需要既线程安全又高性能的解决方案,可以考虑使用ConcurrentHashMap


http://www.kler.cn/a/297753.html

相关文章:

  • 如何集成Android平台GB28181设备接入模块?
  • 【Vue】pnpm创建Vue3+Vite项目
  • 学习node.js 十五,短链接,单设备登录,扫码登录
  • js react 基础笔记 (1)
  • 用户登录和注销
  • CSS3美化网页元素
  • SpringBoot2:请求处理原理分析-接口参数的常用注解
  • 如何修复软件中的BUG
  • 鸿蒙(API 12 Beta6版)GPU加速引擎服务【介绍与开发准备】
  • Qt工程实践_06_Qt MSVC2O17编译器下的程序添加VS2017生成的动态链接库方法
  • 《生物学教学》
  • YOLOv8安装配置教程(Windows版)
  • PMP--一、二、三模--分类--14.敏捷--技巧--DoDDoR
  • 【C语言】揭开计数制的面纱:深入浅出二进制及二进制计算
  • C++学习笔记(15)
  • Gorilla/Mux 中的 Session 管理:实现自定义中间件
  • 解锁SQL基础应用新境界:从入门到精通的扩展实践指南(SQL扩展)
  • 力扣题解2181
  • SprinBoot+Vue教务管理系统的设计与实现
  • 深度学习中的常用线性代数知识汇总——第一篇:基础概念、秩、奇异值