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

Java集合List快速实现重复判断的10种方法深度解析

文章目录

    • 引言:为什么需要关注List重复判断?
    • 一、基础实现方法
      • 1.1 暴力双循环法
      • 1.2 HashSet法
    • 二、进阶实现方案
      • 2.1 Stream API实现
      • 2.2 TreeSet排序法
    • 三、高性能优化方案
      • 3.1 并行流处理
      • 3.2 BitSet位图法(仅限整数)
    • 四、第三方库实现
      • 4.1 Guava工具类
      • 4.2 Apache Commons
    • 五、性能测试对比
      • 5.1 测试环境配置
      • 5.2 百万级数据测试结果
    • 六、最佳实践指南
      • 6.1 选择依据矩阵
      • 6.2 避坑指南
    • 七、特殊场景处理
      • 7.1 自定义对象多字段判重
      • 7.2 大数据量分块处理
    • 结语:高效去重的本质

在这里插入图片描述

引言:为什么需要关注List重复判断?

在Java开发中,List集合的重复判断是高频操作场景。不当的实现方式可能导致O(n²)时间复杂度,在百万级数据时产生分钟级延迟。本文通过10种实现方案对比,揭示不同场景下的最优选择。


一、基础实现方法

1.1 暴力双循环法

public static boolean hasDuplicate(List<?> list) {for (int i = 0; i < list.size(); i++) {for (int j = i + 1; j < list.size(); j++) {if (list.get(i).equals(list.get(j))) {return true;}}}return false;
}

复杂度分析:

  • 时间复杂度:O(n²)
  • 空间复杂度:O(1)

1.2 HashSet法

public static boolean hasDuplicateByHashSet(List<?> list) {Set<Object> set = new HashSet<>(list.size());for (Object item : list) {if (!set.add(item)) { // add返回false表示存在重复return true;}}return false;
}

优化点:

  • 初始容量设置为list.size()避免扩容
  • 快速失败机制

二、进阶实现方案

2.1 Stream API实现

public static boolean hasDuplicateByStream(List<?> list) {return list.stream().distinct().count() < list.size();
}

特性:

  • 代码简洁
  • 支持并行处理

2.2 TreeSet排序法

public static boolean hasDuplicateByTreeSet(List<?> list) {Set<Object> set = new TreeSet<>(list);return set.size() < list.size();
}

适用场景:

  • 需要自然排序结果
  • 元素实现Comparable接口

三、高性能优化方案

3.1 并行流处理

public static boolean hasDuplicateParallel(List<?> list) {Set<Object> seen = ConcurrentHashMap.newKeySet();return list.parallelStream().anyMatch(e -> !seen.add(e));
}

优势:

  • 利用多核CPU加速
  • 线程安全的并发集合

3.2 BitSet位图法(仅限整数)

public static boolean hasDuplicateByBitSet(List<Integer> list) {BitSet bitSet = new BitSet();for (Integer num : list) {if (bitSet.get(num)) return true;bitSet.set(num);}return false;
}

限制:

  • 仅适用于正整数
  • 内存占用与最大数值相关

四、第三方库实现

4.1 Guava工具类

import com.google.common.collect.Sets;public static boolean hasDuplicateByGuava(List<?> list) {return Sets.newHashSet(list).size() < list.size();
}

4.2 Apache Commons

import org.apache.commons.collections4.CollectionUtils;public static boolean hasDuplicateByCommons(List<?> list) {return CollectionUtils.getCardinalityMap(list).values().stream().anyMatch(count -> count > 1);
}

五、性能测试对比

5.1 测试环境配置

硬件规格
CPUIntel i7-12700H
内存32GB DDR5
JDKOracle JDK 17.0.2

5.2 百万级数据测试结果

方法10万元素(ms)100万元素(ms)线程安全
暴力双循环12,345超时(>5min)
HashSet18210
Stream25320
并行流1595
BitSet845

六、最佳实践指南

6.1 选择依据矩阵

小数据
大数据
数据类型
是否基础类型?
BitSet优化
**加粗样式**B
需要排序?
TreeSet
数据规模
HashSet
并行流

6.2 避坑指南

  1. 对象必须正确重写equals/hashCode
class User {private Long id;@Overridepublic boolean equals(Object o) {if (this == o) return true;if (!(o instanceof User user)) return false;return Objects.equals(id, user.id);}@Overridepublic int hashCode() {return Objects.hash(id);}
}
  1. 并发场景使用线程安全容器
Set<Object> safeSet = Collections.synchronizedSet(new HashSet<>());
  1. 避免在Stream中使用有状态操作
// 错误示例:并行流中可能导致漏判
list.parallelStream().forEach(e -> {if (set.contains(e)) flag = true;set.add(e);
});

七、特殊场景处理

7.1 自定义对象多字段判重

public static boolean hasDuplicateByMultiField(List<User> users) {Set<String> seen = new HashSet<>();return users.stream().map(u -> u.getName() + "|" + u.getEmail()).anyMatch(key -> !seen.add(key));
}

7.2 大数据量分块处理

public static boolean hasDuplicateInChunks(List<?> list, int chunkSize) {for (int i = 0; i < list.size(); i += chunkSize) {List<?> subList = list.subList(i, Math.min(i + chunkSize, list.size()));if (hasDuplicateByHashSet(subList)) {return true;}}return false;
}

结语:高效去重的本质

选择最优重复判断方法的核心在于理解数据结构特性业务场景需求的匹配。通过本文的测试数据可知,合理选择算法可以将百万级数据的判断时间从分钟级压缩到毫秒级。

相关文章:

Java集合List快速实现重复判断的10种方法深度解析

文章目录 引言&#xff1a;为什么需要关注List重复判断&#xff1f;一、基础实现方法1.1 暴力双循环法1.2 HashSet法 二、进阶实现方案2.1 Stream API实现2.2 TreeSet排序法 三、高性能优化方案3.1 并行流处理3.2 BitSet位图法&#xff08;仅限整数&#xff09; 四、第三方库实…...

List的模拟实现(2)

前言 上一节我们讲解了list的基本功能&#xff0c;那么本节我们就结合底层代码来分析list是怎么实现的&#xff0c;那么废话不多说&#xff0c;我们正式进入今天的学习&#xff1a;&#xff09; List的底层结构 我们先来看一下list的底层基本结构&#xff1a; 这里比较奇怪的…...

如何使用SaltStack批量替换SSL证书方案

以下是借助 SaltStack 批量替换 SSL 证书的完整方案&#xff0c;该方案结合了自动化更新与回滚机制&#xff0c;以保障操作的高效性与安全性&#xff1a; 一、准备工作 目录结构搭建 在 Salt Master 的 /home/salt/ssl_update 目录下构建如下结构&#xff1a;ssl_update/ ├──…...

Golang快速上手01/Golang基础

最近有需求&#xff0c;需要使用go&#xff0c;这几天快速过一遍基础语法&#xff0c;这是今天的总结 项目结构 #mermaid-svg-qpF09pnIik9bqQ4E {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-qpF09pnIik9bqQ4E .e…...

[Web 安全] 反序列化漏洞 - 学习笔记

关注这个专栏的其他相关笔记&#xff1a;[Web 安全] Web 安全攻防 - 学习手册-CSDN博客 0x01&#xff1a;反序列化漏洞 — 漏洞介绍 反序列化漏洞是一种常见的安全漏洞&#xff0c;主要出现在应用程序将 序列化数据 重新转换为对象&#xff08;即反序列化&#xff09;的过程中…...

【学习笔记】Google的Lyra项目:基于神经网络的超低比特率语音编解码技术

一、引言&#xff1a;语音通信的带宽挑战与技术突破 在实时音视频通信占据全球数字化生活核心地位的今天&#xff0c;Google于2021年推出的Lyra编解码器标志着语音编码技术进入新的时代。这款基于机器学习的新型音频编解码器以3kbps的极低比特率实现接近原始音质的语音重建能力…...

Unity Dedicated Server 控制台 输出日志LOg 中文 乱码

现象: 中文乱码 原因: Unity打包出来的.exe文件&#xff0c;语言一栏是英文&#xff0c;VS控制台出来不一样 解决方案: 新建.bat文件 &#xff0c;并使用命令chcp 65001&#xff0c;运行时启动.bat&#xff0c;而不是.exe, 改不了exe属性&#xff0c;虽然有点奇怪&#xff…...

【Excel】 Power Query抓取多页数据导入到Excel

抓取多页数据想必大多数人都会&#xff0c;只要会点编程技项的人都不会是难事儿。那么&#xff0c;如果只是单纯的利用Excel软件&#xff0c;我还真的没弄过。昨天&#xff0c;我就因为这个在网上找了好久发好久。 1、在数据-》新建查询-》从其他源-》自网站 &#xff0c;如图 …...

去耦电容的作用详解

在霍尔元件的实际应用过程中&#xff0c;经常会用到去耦电容。去耦电容是电路中装设在元件的电源端的电容&#xff0c;其作用详解如下&#xff1a; 一、基本概念 去耦电容&#xff0c;也称退耦电容&#xff0c;是把输出信号的干扰作为滤除对象。它通常安装在集成电路&#xf…...

HTTPS 与 HTTP 的区别在哪?

HTTP与HTTPS作为互联网数据传输的核心协议&#xff0c;其通信机制与安全特性深刻影响着现代网络应用的可靠性与用户体验。本文将解析两者的通信流程、安全机制及核心差异。 一、HTTP的通信机制 先来看看HTTP是什么吧。 HTTP基于TCP/IP协议栈&#xff0c;采用经典客户端-服务…...

let、const【ES6】

‌“我唯一知道的就是我一无所知。” - 苏格拉底 目录 块级作用域&#xff1a;var、let、const的对比&#xff1a;Object.freeze()&#xff1a; 块级作用域&#xff1a; 块级作用域指由 {} 包围的代码块&#xff08;如 if、for、while、单独代码块等&#xff09;形成的独立作用…...

openharmony5.0中hdf框架中实现驱动程序的动态加载和管理的技术细节分析

在分析openharmony的hdf框架的设备驱动加载器(IDriverLoader)时发现在创建实例时会首先判断一下是否完成了驱动入口的构建(HdfDriverEntryConstruct)&#xff0c;如果没有构建会重新构建&#xff0c;这与我开始以为的不一致(我一直以为是采用的linux内核方式&#xff0c;只是由…...

TVS管学习记录

文章目录 前言一、TVS是什么&#xff1f;二、TVS关键参数1.反向截至电压**实际意义** 2.钳位电压**定义与作用****选择依据** **4. 实际应用示例****场景&#xff1a;通信端口的ESD保护** 3.反向截至电压和钳位电压的关联和区别**. 小结** 三、实际应用电路举例总结 前言 TVS管…...

数据库表的各种设计

本篇文章&#xff0c;主要讲解项目开发时&#xff0c;遇到不同的情况&#xff0c;要学会对数据库的表进行合理设计。 1、将表的某个字段&#xff0c;存到一张新表中 ①情况描述 ②操作步骤 第一步&#xff1a;创建role表 第二步&#xff1a;在user表中&#xff0c;删除role字…...

JWT使用教程

目录 JWT (JSON Web Token)1. JWT简介(1) 什么是JWT(2) JWT有什么用(3) JWT认证方式 2. JWT的组成部分3. 签名的目的4. JWT与Token的区别5 JWT的优势6 JJWT签发与验证token(1) 引入依赖(2) 创建 Token(3) 解析Token(4) 设置过期时间(5) 自定义claims 7. JWT自定义工具类 JWT (J…...

【大模型系列篇】如何解决DeepSeek-R1结构化输出问题,使用PydanticAl和DeepSeek构建结构化Agent

今日号外&#xff1a;&#x1f525;&#x1f525;&#x1f525; DeepSeek开源周&#xff1a;炸场&#xff01;DeepSeek开源FlashMLA&#xff0c;提升GPU效率 下面我们开始今天的主题&#xff0c;deepseek官方明确表示deepseek-r1目前不支持json输出/function call&#xff0c;可…...

老旧android项目编译指南(持续更)

原因 编译了很多项目&#xff0c;找到了一些可观的解决办法 1. android studio里面的jdk版本切换 jdk版本切换在这里&#xff0c;一般安卓开发需要用到4个版本的jdk,jdk8, jdk11, jdk17, jdk21新版的android stuio是默认使用高版本的jdk,所以切换版本是很有必要的 2. 命令…...

linux中安装部署Jenkins,成功构建springboot项目详细教程

参考别人配置Jenkins的git地址为https&#xff0c;无法连上github拉取项目&#xff0c;所以本章节介绍通过配置SSH地址来连github拉取项目 目录&#xff1a; 1、springboot项目 1.1 创建名为springcloudproject的springboot项目工程 1.2 已将工程上传到github中&#xff0c;g…...

AI开发利器:Anaconda

在Python开发过程中&#xff0c;不同的项目可能会依赖不同版本的Python以及各种不同版本的库。比如&#xff0c;项目A可能依赖Python 3.8和某个特定版本的numpy、TensorFlow和PyTorch&#xff0c;而项目B可能需要Python 3.9以及另一个版本的numpy库。如果直接在系统中安装Pytho…...

java网络编程--基于TCP协议的网络编程

Scoket介绍 利用 TCP 协议进行通信的两个应用程序是有主次之分的&#xff0c; 一个是服务器程序&#xff0c;一个是客户端程序&#xff0c; 两者的功能和编写方法不太一样&#xff0c; 其中 ServerSocket 类表示 Socket 服务器端&#xff0c;Socket 类表示 Socket 客户端。 服…...

QWEN-AUDIO企业落地:呼叫中心坐席辅助语音+实时话术情感匹配系统

QWEN-AUDIO企业落地&#xff1a;呼叫中心坐席辅助语音实时话术情感匹配系统 1. 呼叫中心智能化升级需求 现代呼叫中心正面临前所未有的挑战。传统模式下&#xff0c;客服人员需要同时处理客户咨询、记录信息、查找资料&#xff0c;还要保持专业友好的服务态度。这种高强度的工…...

3分钟掌握MouseJiggler:告别屏幕锁定的终极效率指南

3分钟掌握MouseJiggler&#xff1a;告别屏幕锁定的终极效率指南 【免费下载链接】mousejiggler Mouse Jiggler is a very simple piece of software whose sole function is to "fake" mouse input to Windows, and jiggle the mouse pointer back and forth. 项目…...

再次革新 .NET 的构建和发布方式(一)任

本文能帮你解决什么&#xff1f; 1. 搞懂FastAPI异步&#xff08;async/await&#xff09;到底在什么场景下能真正提升性能。 2. 掌握在FastAPI中正确使用多线程处理CPU密集型任务的方法。 3. 避开常见的坑&#xff08;比如阻塞操作、数据库连接池耗尽、GIL限制&#xff09;。 …...

4步实现FanControl中文配置:让风扇调节效率提升60%

4步实现FanControl中文配置&#xff1a;让风扇调节效率提升60% 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trending/fa/Fa…...

Pixel Couplet Gen 惊艳像素春联作品集:AI与传统文化的创意碰撞

Pixel Couplet Gen 惊艳像素春联作品集&#xff1a;AI与传统文化的创意碰撞 1. 开篇&#xff1a;当像素艺术遇上传统春联 春节贴春联是中国人延续千年的传统习俗&#xff0c;而如今人工智能为这一古老文化注入了全新活力。Pixel Couplet Gen模型通过独特的像素艺术风格&#…...

【Python机器学习】零基础掌握SGDClassifier线性分类器

如何准确地分类两种不同的水果? 在日常生活中,人们经常需要区分事物,比如水果。假设有两种水果:苹果和橙子,它们在颜色、重量、直径等多个方面有所不同。那么,如何从这些属性中准确地识别这两种水果呢? 想象一下,某个水果店想要自动化他们的库存管理系统。他们有两种…...

百川2-13B-4bits+OpenClaw:科研实验记录自动化整理方案

百川2-13B-4bitsOpenClaw&#xff1a;科研实验记录自动化整理方案 1. 科研工作者的痛点与自动化契机 作为一名长期泡在实验室的研究员&#xff0c;我深知实验记录整理的痛苦。每天面对LabArchives里杂乱无章的实验数据、仪器导出的CSV文件和各种手写笔记&#xff0c;光是整理…...

Java的运行时数据区

Java虚拟机在执行Java程序时会把它所管辖的内存划分为若干个区域&#xff0c;这些区域各有用途&#xff0c;生命周期也各自不同。1、程序计数器。是每条线程都有的一小块私有区域。在程序执行时&#xff0c;一个CPU内核内只能有一条线程执行&#xff0c;不会有多条线程并行执行…...

Xilinx Video IP(二)AXI4-Stream视频数据流与FIFO深度优化

1. AXI4-Stream视频数据流基础 第一次接触Xilinx的Video IP时&#xff0c;很多人会被AXI4-Stream接口搞得一头雾水。其实把它想象成一条传送带就很好理解了——视频数据就像流水线上的包裹&#xff0c;按照固定节奏从源头运送到目的地。这条"传送带"有几个关键特性&a…...

图片旋转判断在智能相册中的创新应用

图片旋转判断在智能相册中的创新应用 1. 引言 你有没有遇到过这样的情况&#xff1f;翻看手机相册时&#xff0c;发现有些照片莫名其妙地歪了&#xff0c;需要手动一张张旋转校正。特别是那些横屏拍摄的照片&#xff0c;在手机竖屏查看时总是需要歪着头看&#xff0c;体验特别…...