如何删除 HashMap 中的重复元素?—— 99% 的人不知道的第 3 种实现思路

简介: 如何删除 HashMap 中的重复元素?—— 99% 的人不知道的第 3 种实现思路

在 Java 开发中,HashMap 是一种常用的数据结构,用于存储键值对。它具有快速查找的特点,因此在许多场合都被广泛应用。然而,当我们使用 HashMap 时,有时可能会遇到需要删除重复元素的情况。

在这篇文章中,我们将探讨三种不同的方法来处理 HashMap 中的重复元素,并重点讲解最后一种使用 Stream 的方法,很多人对此并不熟悉。

一、HashMap 的特点

首先,让我们了解一下 HashMap 的几个主要特点:

  1. 唯一性:HashMap 中的 key 是唯一的。如果你尝试插入相同的 key,它会将新值覆盖旧值。
  2. 无序性:HashMap 不保证其元素的顺序。即使是相同的插入顺序,遍历时也可能得到不同的顺序。
  3. 效率高:HashMap 基于哈希表实现,提供 O(1) 的平均时间复杂度用于查找和插入操作。
  4. 允许 null 值:HashMap 可以存储 null 值(作为值和一个 key)。

这些特点使得 HashMap 在许多开发场景中成为首选数据结构,例如缓存、图书管理系统等。

现实生活中的类比

想象一下,你有一个字典,每个单词(key)都对应一个定义(value)。如果你再次输入已经存在的单词,字典会更新这个单词的定义,而不是重复添加。这就是 HashMap 的主要特性。

二、为什么要删除 HashMap 中的重复元素?

在某些情况下,尽管 HashMap 中的 key 是唯一的,但值(value)可能会重复。例如,在用户注册系统中,有多个用户可能因为错误或重复提交而使用同样的邮箱地址。为了确保数据的唯一性和一致性,我们需要从 HashMap 中删除重复的值。

三、三种实现思路

接下来,我们将介绍三种不同的方法来删除 HashMap 中的重复元素。

方法一:新创建 Map 添加不重复元素

这种方法简单直接,我们可以遍历原来的 HashMap,将不重复的元素添加到一个新的 HashMap 中。

import java.util.HashMap;
import java.util.Map;
 
public class RemoveDuplicatesExample1 {
    public static void main(String[] args) {
        // 原始 HashMap
        HashMap<String, String> originalMap = new HashMap<>();
        originalMap.put("001", "Java Programming");
        originalMap.put("002", "Data Structures");
        originalMap.put("003", "Java Programming"); // 重复元素
 
        // 新建一个 HashMap 存放不重复的元素
        HashMap<String, String> uniqueMap = new HashMap<>();
 
        // 遍历原始 HashMap
        for (Map.Entry<String, String> entry : originalMap.entrySet()) {
            // 如果 uniqueMap 不包含该值,则添加
            if (!uniqueMap.containsValue(entry.getValue())) {
                uniqueMap.put(entry.getKey(), entry.getValue());
            }
        }
 
        // 输出结果
        System.out.println("Unique Map: " + uniqueMap);
    }
}
解析:
  1. 创建一个新的 uniqueMap。
  2. 遍历原始的 originalMap,检查是否已经存在相同的 value。
  3. 将不重复的键值对添加到新的 HashMap 中。

方法二:添加 Set 再删除重复元素

这个方法利用了 Set 集合的特性,因为 Set 不允许存储重复元素。我们可以先把所有的值添加到一个 Set 中,再根据这个 Set 来构建新的 HashMap。

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
 
public class RemoveDuplicatesExample2 {
    public static void main(String[] args) {
        // 原始 HashMap
        HashMap<String, String> originalMap = new HashMap<>();
        originalMap.put("001", "Java Programming");
        originalMap.put("002", "Data Structures");
        originalMap.put("003", "Java Programming"); // 重复元素
 
        // 使用 Set 存储唯一的值
        Set<String> uniqueValues = new HashSet<>(originalMap.values());
 
        // 新建一个 HashMap 存放不重复的元素
        HashMap<String, String> uniqueMap = new HashMap<>();
 
        // 遍历原始 HashMap,并基于 Set 构建新 HashMap
        for (String value : uniqueValues) {
            for (Map.Entry<String, String> entry : originalMap.entrySet()) {
                if (entry.getValue().equals(value)) {
                    uniqueMap.put(entry.getKey(), entry.getValue());
                    break; // 找到后跳出内层循环
                }
            }
        }
 
        // 输出结果
        System.out.println("Unique Map using Set: " + uniqueMap);
    }
}
解析:
  1. 将原始 HashMap 的所有值存入 Set 中,以便自动去重。
  2. 通过两层循环,将基于 Set 的唯一值构建新的 HashMap。

方法三:使用 Stream 删除重复元素

这是最现代化的方法,使用 Java 8 引入的 Stream API,可以让代码更加简洁。Stream 可以帮助我们更高效地处理集合数据。

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
 
public class RemoveDuplicatesExample3 {
    public static void main(String[] args) {
        // 原始 HashMap
        HashMap<String, String> originalMap = new HashMap<>();
        originalMap.put("001", "Java Programming");
        originalMap.put("002", "Data Structures");
        originalMap.put("003", "Java Programming"); // 重复元素
 
        // 使用 Stream 去重
        Map<String, String> uniqueMap = originalMap.entrySet()
                .stream()
                .filter(entry -> 
                        originalMap.values().stream().filter(v -> v.equals(entry.getValue())).count() == 1)
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
 
        // 输出结果
        System.out.println("Unique Map using Stream: " + uniqueMap);
    }
}
解析:
  1. 使用 entrySet() 获取所有条目并转为流式操作。
  2. 通过 filter() 方法仅保留那些只出现一次的值。
  3. 最后,通过 collect() 方法将结果收集到新的 HashMap 中。

四、为什么不是根据 Key 去重?

如前所述,HashMap 的 key 是唯一的。如果我们尝试插入一个已有的 key,新值将替换旧值,因此在 HashMap 中“去重”实际上指的是值(value)的去重。

实际例子

例如,在一个用户注册系统中,邮箱地址通常作为 key 存储相关用户信息。如果同一邮箱被多次注册,我们希望保留最后一次的注册信息,而不是删除或覆盖它们。这就是我们需要对 values 进行去重的原因。

五、总结

在本文中,我们探讨了在 HashMap 中删除重复元素的三种方法:

  1. 新创建 Map 添加不重复元素:简单直观,适合新手理解。
  2. 添加 Set 再删除重复元素:利用 Set 的特性实现去重。
  3. 使用 Stream 删除重复元素:现代化的方式,适合熟悉 Java 8 的开发者。

希望这篇文章能帮助你理解如何在 HashMap 中处理重复元素的问题!如果你还有其他问题或者想了解更多,请随时提问。

相关文章
|
2月前
|
Java 索引
让星星⭐月亮告诉你,HashMap之往红黑树添加元素-putTreeVal方法源码解读
本文详细解析了Java `HashMap` 中 `putTreeVal` 方法的源码,该方法用于在红黑树中添加元素。当数组索引位置已存在红黑树类型的元素时,会调用此方法。具体步骤包括:从根节点开始遍历红黑树,找到合适位置插入新元素,调整节点指针,保持红黑树平衡,并确保根节点是链表头节点。通过源码解析,帮助读者深入理解 `HashMap` 的内部实现机制。
40 2
|
6月前
|
存储 算法 Java
Java查找算法概览:二分查找适用于有序数组,通过比较中间元素缩小搜索范围;哈希查找利用哈希函数快速定位,示例中使用HashMap存储键值对,支持多值关联。
【6月更文挑战第21天】Java查找算法概览:二分查找适用于有序数组,通过比较中间元素缩小搜索范围;哈希查找利用哈希函数快速定位,示例中使用HashMap存储键值对,支持多值关联。简单哈希表实现未涵盖冲突解决和删除操作。
67 1
|
小程序 Java 程序员
面试官:怎么删除 HashMap 中的重复元素?第 3 种实现思路,99% 的人不会!
面试官:怎么删除 HashMap 中的重复元素?第 3 种实现思路,99% 的人不会!
138 0
|
安全 小程序 Java
面试官:怎么删除 HashMap 中的元素?我一行代码搞定,赶紧拿去用!
面试官:怎么删除 HashMap 中的元素?我一行代码搞定,赶紧拿去用!
223 0
|
安全 小程序 Java
面试官:怎么删除 HashMap 中的元素?我一行代码搞定,赶紧拿去用!
面试官:怎么删除 HashMap 中的元素?我一行代码搞定,赶紧拿去用!
130 0
HashMap、HashSet、TreeMap、TreeSet判断元素相同
HashMap、HashSet、TreeMap、TreeSet判断元素相同   目录 1.1     HashMap 1.2     HashSet 1.3     TreeMap 1.4     TreeSet   1.1     HashMap        先来看一下HashMap里面是怎么存放元素的。
965 0
|
2月前
|
Java
让星星⭐月亮告诉你,HashMap中保证红黑树根节点一定是对应链表头节点moveRootToFront()方法源码解读
当红黑树的根节点不是其对应链表的头节点时,通过调整指针的方式将其移动至链表头部。具体步骤包括:从链表中移除根节点,更新根节点及其前后节点的指针,确保根节点成为新的头节点,并保持链表结构的完整性。此过程在Java的`HashMap$TreeNode.moveRootToFront()`方法中实现,确保了高效的数据访问与管理。
31 2
|
2月前
|
算法 Java 容器
Map - HashSet & HashMap 源码解析
Map - HashSet & HashMap 源码解析
62 0