0

0

如何在Java中查找List集合中的重复元素_分组统计与过滤方案

P粉602998670

P粉602998670

发布时间:2026-03-06 09:05:03

|

307人浏览过

|

来源于php中文网

原创

最直接解法是用collectors.groupingby(function.identity(), collectors.counting())分组计数,再filter取value>1的key;需注意泛型擦除、null安全及避免漏掉entryset().stream()转换。

如何在java中查找list集合中的重复元素_分组统计与过滤方案

Collectors.groupingBy 统计频次再过滤

Java 8+ 最直接的解法不是遍历比对,而是借力流式 API 做分组统计。核心逻辑是:先按元素本身分组计数,再筛出出现次数大于 1 的键。

常见错误是只调用 groupingBy 却忘了接 counting(),导致返回 Map<t list>></t>,白白多占内存;或者漏掉 entrySet().stream() 这一层转换,无法继续过滤。

  • 必须搭配 Collectors.counting(),否则得不到数字频次
  • 结果是 Map<t long></t>,要取重复项得用 entrySet().stream().filter(e -> e.getValue() > 1).map(Map.Entry::getKey).collect(Collectors.toList())
  • 注意泛型擦除:若 List 是原始类型或含 nullgroupingBy 会抛 NullPointerException
List<String> list = Arrays.asList("a", "b", "a", "c", "b", "b");
List<String> duplicates = list.stream()
    .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
    .entrySet().stream()
    .filter(e -> e.getValue() > 1)
    .map(Map.Entry::getKey)
    .collect(Collectors.toList()); // ["a", "b"]

Set 辅助做单次遍历去重判断

如果只要知道哪些元素重复、不关心重复几次,且对性能敏感(尤其大数据量),用 HashSet 辅助是更轻量的选择:边遍历边记录已见元素,第二次遇到即为重复。

容易踩的坑是误用 add() 返回值逻辑——它返回 false 表示“已存在”,但新手常写成 if (set.add(e)) { /* 重复 */ },实际应是 if (!set.add(e))

立即学习Java免费学习笔记(深入)”;

Dreamhouse AI
Dreamhouse AI

AI室内设计,快速重新设计你的家,虚拟布置家具

下载
  • Set.add() 返回 true 表示新增成功,false 表示已存在
  • 重复元素可能被多次加入结果集,需额外用 LinkedHashSet 去重并保序
  • 该方法不支持 null 元素(除非用 ConcurrentHashMap.newKeySet() 等替代)
Set<String> seen = new HashSet<>();
Set<String> duplicates = new LinkedHashSet<>();
for (String item : list) {
    if (!seen.add(item)) {
        duplicates.add(item);
    }
}

Collections.frequency 的陷阱与适用场景

这个工具方法看着简单,但实际只适合小列表或调试场景。它内部是遍历计数,对每个元素都全表扫描一次,时间复杂度是 O(n²),10 万条数据就明显卡顿。

典型误用是嵌套在循环里反复调用,比如先 for (String s : list)if (Collections.frequency(list, s) > 1),等于把 O(n²) 执行了 n 次,变成 O(n³)。

  • 仅建议用于长度
  • 不要在循环体内调用,可先去重(new HashSet(list)),再对外层集合遍历调用
  • 返回值是 int,但传入 null 时行为取决于具体 List 实现(如 ArrayList 支持,Arrays.asList 包装的数组不支持)

自定义对象重复判断必须重写 equalshashCode

如果 List 装的是自定义类(如 User),所有上述方案都会失效——除非你明确告诉 JVM “两个对象什么时候算同一个”。默认的引用比较会让所有对象都不同。

最常被忽略的是只重写 equals 忘了 hashCode,导致 HashSetgroupingBy 分组错乱:相同对象被散列到不同桶,统计结果漏项或重复。

  • 必须同时重写 equalshashCode,且逻辑一致(比如都基于 id 字段)
  • 字段选型要稳定:避免用可变字段(如 name)做判等依据,否则对象修改后哈希值变化,集合行为不可预测
  • IDE 生成的模板基本可用,但要注意是否包含 null 安全检查(推荐用 Objects.equals(a, b)

重复判定本质是“相等性定义”问题,不是算法问题。没重写 equals/hashCode 就跑分组统计,结果一定不对;用 frequency 处理大列表,线程会卡住;而依赖 Set 辅助时,add() 的布尔返回值方向搞反,就永远抓不到重复项。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

950

2023.08.02

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

252

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1029

2024.03.01

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

841

2023.08.22

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

950

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

604

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

294

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

212

2025.08.29

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

19

2026.03.05

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 4.1万人学习

C# 教程
C# 教程

共94课时 | 10.7万人学习

Java 教程
Java 教程

共578课时 | 77.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号