HashMap<K, V>

HashMap<K, V> 是 Java 集合框架中用于存储键值对的重要类,它位于 java.util 包下,实现了 Map<K, V> 接口。下面从多个方面为你详细介绍 HashMap<K, V>

特性

  1. 键值对存储HashMap 以键值对(key - value)的形式存储数据,每个键都是唯一的,键可以为 null,但只能有一个 null 键,值可以有多个 null
  2. 无序性:不保证键值对的存储顺序,即插入的顺序和遍历的顺序可能不同。
  3. 基于哈希表实现:利用哈希函数将键映射到哈希表的特定位置,从而实现快速的插入、删除和查找操作。
  4. 非线程安全:在多线程环境下,如果多个线程同时访问并修改 HashMap,可能会导致数据不一致或抛出异常。

构造方法

  1. HashMap():创建一个默认初始容量为 16,负载因子为 0.75 的空 HashMap
import java.util.HashMap;

public class HashMapExample {
    public static void main(String[] args) {
        HashMap<String, Integer> map = new HashMap<>();
    }
}

  1. HashMap(int initialCapacity):创建一个指定初始容量,负载因子为 0.75 的空 HashMap
HashMap<String, Integer> map = new HashMap<>(32);

  1. HashMap(int initialCapacity, float loadFactor):创建一个指定初始容量和负载因子的空 HashMap
HashMap<String, Integer> map = new HashMap<>(32, 0.8f);

  1. HashMap(Map<? extends K, ? extends V> m):创建一个包含指定 Map 中所有键值对的 HashMap
import java.util.HashMap;
import java.util.Map;

public class HashMapExample {
    public static void main(String[] args) {
        Map<String, Integer> anotherMap = new HashMap<>();
        anotherMap.put("apple", 1);
        HashMap<String, Integer> map = new HashMap<>(anotherMap);
    }
}

常用方法

  1. 插入和更新操作put(K key, V value):将指定的键值对插入到 HashMap 中。如果键已经存在,则更新该键对应的值。返回该键之前关联的值,如果键不存在则返回 null。
HashMap<String, Integer> map = new HashMap<>();
Integer oldValue = map.put("apple", 1);

- **`putAll(Map<? extends K, ? extends V> m)`**:将指定 `Map` 中的所有键值对复制到当前 `HashMap` 中。

Map<String, Integer> anotherMap = new HashMap<>();
anotherMap.put("banana", 2);
map.putAll(anotherMap);

  1. 删除操作remove(Object key):从 HashMap 中移除指定键对应的键值对。返回该键关联的值,如果键不存在则返回 null。
Integer removedValue = map.remove("apple");

  1. 查询操作get(Object key):返回指定键关联的值,如果键不存在则返回 null。
Integer value = map.get("apple");

- **`containsKey(Object key)`**:判断 `HashMap` 中是否包含指定的键,包含返回 `true`,否则返回 `false`。

boolean hasKey = map.containsKey("apple");

- **`containsValue(Object value)`**:判断 `HashMap` 中是否包含指定的值,包含返回 `true`,否则返回 `false`。

boolean hasValue = map.containsValue(1);

- **`size()`**:返回 `HashMap` 中键值对的数量。

int size = map.size();

  1. 遍历操作keySet():返回一个包含 HashMap 中所有键的 Set 视图。可以通过遍历该 Set 来访问 HashMap 中的键和对应的值。
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

HashMap<String, Integer> map = new HashMap<>();
map.put("apple", 1);
map.put("banana", 2);
Set<String> keySet = map.keySet();
for (String key : keySet) {
    Integer value = map.get(key);
    System.out.println(key + ": " + value);
}

- **`values()`**:返回一个包含 `HashMap` 中所有值的 `Collection` 视图。

import java.util.Collection;

Collection<Integer> values = map.values();
for (Integer value : values) {
    System.out.println(value);
}

- **`entrySet()`**:返回一个包含 `HashMap` 中所有键值对的 `Set` 视图,每个键值对用 `Map.Entry<K, V>` 对象表示。这种方式是最常用的遍历 `HashMap` 的方式,因为它可以同时访问键和值,并且效率较高。

import java.util.Map.Entry;

Set<Entry<String, Integer>> entrySet = map.entrySet();
for (Entry<String, Integer> entry : entrySet) {
    String key = entry.getKey();
    Integer value = entry.getValue();
    System.out.println(key + ": " + value);
}

注意事项

  1. 哈希冲突:当不同的键通过哈希函数计算得到相同的哈希值时,会发生哈希冲突。HashMap 使用链表或红黑树来解决哈希冲突。当链表长度超过 8 且数组长度大于 64 时,链表会转换为红黑树,以提高查找效率。
  2. 负载因子和扩容:负载因子(默认为 0.75)表示哈希表在达到多满时进行扩容。当哈希表中的键值对数量超过 容量 * 负载因子 时,会进行扩容操作,将哈希表的容量扩大为原来的 2 倍,并重新计算所有键的哈希位置。
  3. 线程安全问题:如果需要在多线程环境下使用,可以考虑使用 ConcurrentHashMap 或通过 Collections.synchronizedMap 方法将 HashMap 包装成线程安全的 Map
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

Map<String, Integer> synchronizedMap = Collections.synchronizedMap(new HashMap<>());

综上所述,HashMap 是一个非常实用的集合类,适合在大多数需要存储键值对的场景中使用,但在多线程环境下需要注意线程安全问题。

Java集合框架 文章被收录于专栏

Java集合框架是Java提供的一组用于存储和操作数据的类和接口,它位于java.util包中,为开发者提供了强大且灵活的数据存储和处理能力。以下将从整体架构、主要接口、常用实现类、使用场景以及示例代码等方面详细介绍Java集合框架。

全部评论

相关推荐

柠檬微趣面经1.&nbsp;游戏客户端开发实习(2026届)面试流程:笔试&nbsp;→&nbsp;一面&nbsp;→&nbsp;二面&nbsp;→&nbsp;三面(加面)&nbsp;→&nbsp;HR面(通过)笔试:4道编程题(LeetCode中等难度)面试重点:一面:-&nbsp;指针大小、指针和引用的区别-&nbsp;`#include&amp;amp;lt;&amp;amp;gt;`和`include&amp;amp;quot;&amp;amp;quot;`的区别-&nbsp;哈希表&nbsp;vs&nbsp;二叉树适用场景-&nbsp;手撕算法:DFS、前缀和-&nbsp;智力题:飞机飞行时差问题二面:-&nbsp;二叉树遍历(题目理解错误,调整后正确)-&nbsp;计算时针和分针夹角(紧张算错,后修正)-&nbsp;链表相交情况分析(画图)三面(加面):-&nbsp;0、1互换的多种方法(一面重复问)-&nbsp;链表相关题目(口述思路)HR面:常规问题,顺利通过面试体验:面试官友好,流程快,部分题目重复考察。2.&nbsp;C++后台开发(2025届)面试流程:笔试&nbsp;→&nbsp;一面(挂)笔试:4道编程题(二叉树、字符串处理、数组有序对)面试重点:一面:-&nbsp;进程通信(信号、共享内存)-&nbsp;TCP三次握手/四次挥手(TIMEWAIT作用)-&nbsp;虚函数原理(虚表指针存储位置)-&nbsp;同步&nbsp;vs&nbsp;异步、阻塞&nbsp;vs&nbsp;非阻塞-&nbsp;笔试复盘(优化最大有序对长度算法)面试体验:基础不扎实导致挂掉,面试官追问深入细节。柠檬微趣2025届校招&amp;amp;amp;26届实习进行中【招聘动态】研发类、数据类、策划类三大岗位仍有较多机会,欢迎投递【关于我们】中国领先的手机休闲游戏开发商和运营商之一,研发发行的爆款游戏有《宾果消消消》、《浪漫餐厅》等,柠檬微趣已成为合成手游赛道全球收入最高发行商!【福利待遇】-&nbsp;北京户口指标、一年免费住宿-&nbsp;七险一金、丰厚年终奖、免费早晚餐-&nbsp;带薪年假、带薪全员旅游、年度体检-&nbsp;社团活动、生日礼物、水果下午茶⭐【内推链接】https://app.mokahr.com/su/lodoap【内推码】NTA0tU4(简历优先筛选,后续疑问/流程问题欢迎联系)大家投递完可以在评论区打上姓名缩写+岗位,我来确认有没有内推成功喽 #春招#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#实习#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#内推#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#内推码#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#柠檬微趣#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务