Java中HashMap的使用操作

 更新时间:2025年08月26日 09:38:54   作者:熙客  
HashMap位于java.util包下,它实现了Map接口,提供了基于键值对(Key-Value)的数据存储方式,并允许使用null作为键和值,这篇文章主要介绍了Java中HashMap的使用,需要的朋友可以参考下

一、概念

HashMap 位于 java.util 包下。它实现了 Map 接口,提供了基于键值对(Key-Value)的数据存储方式,并允许使用 null 作为键和值。

核心思想:使用“键(Key)”的哈希值来存储和检索“值(Value)”。

核心特点:

  • 基于哈希表:它使用哈希算法来存储和检索数据,这使得在理想情况下,get 和 put 操作的时间复杂度可以达到 O(1)
  • 无序HashMap 不保证其中元素的顺序(即插入顺序和访问顺序),并且顺序也可能会随时间(如扩容时)而变化。如果需要有序,可以使用 LinkedHashMap
  • 非线程安全:多个线程同时操作一个 HashMap 可能会导致数据不一致。如果多个线程同时访问一个 HashMap 并至少有一个线程修改了它,则必须在外部进行同步。或者使用 Collections.synchronizedMap() 进行包装,或者更推荐使用 ConcurrentHashMap

二、常用操作

2.1 初始化

// 1. 最常见的无参构造,默认初始容量16,负载因子0.75
HashMap<String, Integer> map = new HashMap<>();
// 2. 指定初始容量(减少扩容次数,优化性能)
HashMap<String, Integer> mapWithCapacity = new HashMap<>(32);
// 3. 指定初始容量和负载因子(高级用法,通常不需要)
HashMap<String, Integer> mapWithFactor = new HashMap<>(32, 0.8f);
// 4. 通过另一个Map来创建
HashMap<String, Integer> anotherMap = new HashMap<>(map);

扩容机制:扩充为原数组容量的2倍

当 HashMap 中的元素数量size超过当前阈值(threshold) 时,就会触发扩容。

阈值 (threshold) = 容量 (capacity) * 负载因子 (load factor)

  • 默认示例:默认容量为 16,默认负载因子为 0.75。
    • 那么阈值就是 16 * 0.75 = 12
    • 当执行 put() 操作后,size 变得大于 12(即 13)时,就会触发扩容。

2.2 CRUD

HashMap<String, String> capitalCities = new HashMap<>();
// 添加与更新
// put(K key, V value) - 添加键值对,如果key已存在,则更新其value
capitalCities.put("USA", "Washington D.C.");
capitalCities.put("Germany", "Berlin");
capitalCities.put("Germany", "Berlin"); // 重复放入,不会改变
capitalCities.put("Germany", "New Berlin"); // Key已存在,Value会被更新为 "New Berlin"
// putIfAbsent(K key, V value) - (Java 8+) 只有在key不存在或对应的value为null时,才放入
capitalCities.putIfAbsent("France", "Paris"); // 会放入,因为France不存在
capitalCities.putIfAbsent("Germany", "Paris"); // 不会放入,因为Germany已存在,Value仍然是"New Berlin"
// 获取元素
// get(Object key) - 根据key获取value,如果key不存在,返回null
String capitalOfGermany = capitalCities.get("Germany"); // "New Berlin"
String capitalOfJapan = capitalCities.get("Japan"); // null
// getOrDefault(Object key, V defaultValue) - (Java 8+) key不存在时返回一个默认值
String capitalOfJapanSafe = capitalCities.getOrDefault("Japan", "Not Found"); // "Not Found"
// 检查元素是否存在
// containsKey(Object key) - 检查某个key是否存在
boolean hasGermany = capitalCities.containsKey("Germany"); // true
boolean hasJapan = capitalCities.containsKey("Japan"); // false
// containsValue(Object value) - 检查某个value是否存在(效率较低,需要遍历)
boolean hasParis = capitalCities.containsValue("Paris"); // true
// 删除元素
// remove(Object key) - 根据key删除键值对,返回被删除的value
String removedValue = capitalCities.remove("Germany"); // removedValue = "New Berlin"
// remove(Object key, Object value) - (Java 8+) 只有当key和value都匹配时才删除
boolean isRemoved = capitalCities.remove("USA", "LA"); // false, 因为Value不匹配"Washington D.C.",删除失败
boolean isRemoved2 = capitalCities.remove("USA", "Washington D.C."); // true, 删除成功

2.3 遍历

// 遍历所有键:keySet()
for (String country : capitalCities.keySet()) {
    System.out.println("Country: " + country);
    // 可以通过key再get value,但效率较低(不推荐在循环内这样用)
    // System.out.println("Capital: " + capitalCities.get(country));
}
// 遍历所有值:values()
for (String capital : capitalCities.values()) {
    System.out.println("Capital: " + capital);
}
// 遍历所有键值对:entrySet() (最推荐、最高效的方式)
for (Map.Entry<String, String> entry : capitalCities.entrySet()) {
    String country = entry.getKey();
    String capital = entry.getValue();
    System.out.println(country + " -> " + capital);
}
// 使用 Java 8 forEach + Lambda 表达式 (最简洁)
capitalCities.forEach((country, capital) -> {
    System.out.println(country + " -> " + capital);
});

2.4 其他常用方法

// size() - 返回键值对的数量
int size = capitalCities.size();
// isEmpty() - 判断是否为空
boolean isEmpty = capitalCities.isEmpty();
// clear() - 清空所有映射
capitalCities.clear();
// replace(K key, V oldValue, V newValue) - (Java 8+) 替换操作
capitalCities.replace("France", "Paris", "Lyon"); // 只有当旧值匹配时才替换

三、与其他Map的比较

特性HashMapLinkedHashMapTreeMapHashtableConcurrentHashMap
排序保证无顺序插入顺序 或 访问顺序 (LRU)键的自然顺序 或 自定义比较器顺序无顺序无顺序
是否允许 null允许 一个 null key 和多个 null value允许 一个 null key 和多个 null value不允许 null key (取决于Comparator)不允许 null key 或 null value不允许 null key 或 null value
线程安全 (非同步) (非同步) (非同步) (同步,每个方法都用 synchronized 修饰) (采用分段锁/CAS等更高效的并发控制)
性能特点O(1) 时间复杂度的 get/put (平均情况)比 HashMap 稍慢,因为要维护链表O(log n) 时间复杂度的 get/put类似 HashMap,但同步开销大,性能差高并发性能极佳,读操作通常无需锁
底层实现数组 + 链表/红黑树 (哈希表)HashMap + 双向链表 (维护顺序)红黑树数组 + 链表 (哈希表)数组 + 链表/红黑树 + CAS + 分段锁 (JDK 7/8 不同)
迭代顺序一致性不保证,甚至可能随时间变化保证,与插入顺序或访问顺序一致保证,根据键的顺序排序不保证不保证
引入版本JDK 1.2JDK 1.4JDK 1.2JDK 1.0 (是古老遗留类)JDK 1.5 (java.util.concurrent 包)

到此这篇关于Java中HashMap的使用操作的文章就介绍到这了,更多相关Java HashMap内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java项目编译后target目录详细介绍

    Java项目编译后target目录详细介绍

    Java项目中的target目录是Maven或Gradle等构建工具在编译和打包过程中生成的重要输出目录,‌这篇文章主要介绍了Java项目编译后target目录的相关资料,需要的朋友可以参考下
    2025-08-08
  • 浅析Java 反射机制的用途和缺点

    浅析Java 反射机制的用途和缺点

    这篇文章给大家分析了Java 反射机制的用途和缺点以及相关知识点内容,有兴趣的朋友可以参考学习下。
    2018-07-07
  • spring boot输入数据校验(validation)的实现过程

    spring boot输入数据校验(validation)的实现过程

    web项目中,用户的输入总是被假定不安全不正确的,在被处理前需要做校验。本文介绍在spring boot项目中实现数据校验的过程,通过实例代码给大家介绍的非常详细,需要的朋友参考下吧
    2021-09-09
  • java接口幂等性的实现方式

    java接口幂等性的实现方式

    本文介绍了在不同层面上实现Java接口幂等性的方法,包括使用幂等表、Nginx+Lua和Redis、以及SpringAOP,通过这些方法,可以确保接口在多次请求时只执行一次,避免重复处理和数据不一致,每种方法都有其适用场景和优势,通过实际测试验证了幂等性逻辑的有效性
    2025-01-01
  • 如何动态修改JavaBean中注解的参数值

    如何动态修改JavaBean中注解的参数值

    这篇文章主要介绍了如何动态修改JavaBean中注解的参数值操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • java中charAt()方法的使用及说明

    java中charAt()方法的使用及说明

    这篇文章主要介绍了java中charAt()方法的使用及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • java 字浮串提取方法汇集

    java 字浮串提取方法汇集

    用方法toCharArray public char[] toCharArray()
    2008-10-10
  • Java如何从集合和数组获取Stream流的方法

    Java如何从集合和数组获取Stream流的方法

    本文详细介绍了Java中如何从集合、数组等数据结构获取Stream流,包括使用Collection接口的stream()和parallelStream()方法、Arrays类的stream()方法、Stream.of()方法以及基本类型数组的流方法等
    2025-01-01
  • SpringBoot实现简易支付宝网页支付功能

    SpringBoot实现简易支付宝网页支付功能

    小编最近实现一个功能基于springboot程序的支付宝支付demo,非常不错适合初学者入门学习使用,今天把SpringBoot实现简易支付宝网页支付功能的示例代码分享给大家,感兴趣的朋友参考下吧
    2021-10-10
  • JAVA基于Arrays.sort()实现数组升序和降序

    JAVA基于Arrays.sort()实现数组升序和降序

    这篇文章主要介绍了JAVA基于Arrays.sort()实现数组升序和降序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06

最新评论