0

0

Java中高效删除文本文件重复行:基于首字段的策略与实现

DDD

DDD

发布时间:2025-12-03 19:34:55

|

510人浏览过

|

来源于php中文网

原创

java中高效删除文本文件重复行:基于首字段的策略与实现

本教程详细阐述了在Java中如何根据行的首个字段识别并删除文本文件中的重复行,并将处理后的数据存储到列表中。文章深入探讨了两种主要方法:一是利用Java Stream API的`Collectors.toMap`结合自定义合并函数直接处理字符串列表;二是引入自定义领域对象(如Company类)来封装数据,并通过对象ID进行去重,从而提升代码的可读性和维护性。教程包含详细的代码示例和实现解析。

在处理文本数据时,我们经常会遇到需要去除重复记录的场景。特别是在日志文件或数据导入导出中,如果重复的定义是基于行内某个特定字段(例如,行的第一个逗号分隔值),那么传统的List.stream().distinct()方法将无法满足需求,因为它会比较整行字符串的完全一致性。本文将介绍如何在Java中,针对以首字段作为重复判断依据的文本行,进行高效的去重操作,并将结果存储到ArrayList中。

理解问题:基于首字段的重复判断

假设我们有一个文本文件,内容如下:

123456,greenwitch street,near dominos store,Opp sandwitch company,Neyork,US,876890
123480,Postwitch street,near KFC store,Opp masala company,Newyork,US,876891
123456,Newyork street,near 100th avenue,King master company,Texas,US,10005

在这个例子中,第一行和第三行的起始数字“123456”是相同的,但行的其余部分不同。我们的目标是删除整个第三行,因为其首字段与第一行重复。

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

解决方案一:利用 Collectors.toMap 直接处理字符串

Java 8引入的Stream API为处理集合数据提供了强大而灵活的工具。Collectors.toMap()方法特别适用于根据某个键值进行聚合或去重。其核心思想是:将每行数据解析出一个作为键(Key)的唯一标识,并将整行数据作为值(Value)存储起来。当遇到重复的键时,通过一个合并函数(mergeFunction)来决定保留哪个值。

OpenArt
OpenArt

在线AI绘画艺术图片生成器工具

下载

1. 核心原理

我们将行的第一个逗号分隔值作为键。如果遇到相同的键,我们选择保留第一次出现的值(即最早的记录)。

2. 代码实现

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

public class DuplicateRowRemover {

    public static void main(String[] args) {
        List sourceList = List.of(
            "123456,greenwitch street,near dominos store,Opp sandwitch company,Neyork,US,876890",
            "123480,Postwitch street,near KFC store,Opp masala company,Newyork,US,876891",
            "123456,Newyork street,near 100th avenue,King master company,Texas,US,10005"
        );

        List uniqueList = sourceList.stream()
            .collect(Collectors.toMap(
                str -> str.substring(0, str.indexOf(',')), // keyMapper: 提取第一个逗号前的子字符串作为键
                Function.identity(),                       // valueMapper: 整行字符串作为值
                (left, right) -> left                      // mergeFunction: 遇到重复键时,保留左边(即第一个遇到的)值
            ))
            .values()                                      // 获取Map中所有的值(即去重后的行)
            .stream()
            .toList();                                     // 转换为List

        System.out.println("去重后的列表 (字符串方式):");
        uniqueList.forEach(System.out::println);
    }
}

3. 代码解析

  • keyMapper (str -> str.substring(0, str.indexOf(','))): 这个函数负责从每行字符串中提取出作为唯一标识的键。它找到第一个逗号的位置,并截取从开头到该位置的子字符串。
  • valueMapper (Function.identity()): 这个函数指定了Map中存储的值。Function.identity()表示将当前流中的元素本身作为值。
  • mergeFunction ((left, right) -> left): 这是处理重复键的关键。当Collectors.toMap在处理流时遇到一个已经存在于Map中的键时,它会调用这个函数来决定保留哪个值。left代表Map中已有的值,right代表当前流中新遇到的值。-> left表示我们选择保留Map中已有的值,即第一个遇到的记录。如果选择-> right,则会保留最后一个遇到的记录。
  • .values().stream().toList(): 在完成收集后,Map中存储的键值对是唯一的。我们通过.values()获取所有去重后的行字符串集合,然后将其转换回List。

解决方案二:引入自定义领域对象(Domain Class)

直接操作字符串虽然简单,但当数据结构复杂、字段较多时,容易出错且代码可读性差。更专业的做法是定义一个领域对象(如Company类)来封装每行数据,并通过对象的ID属性进行去重。这不仅提升了代码的类型安全性和可读性,也为后续的数据操作提供了便利。

1. 定义领域对象

我们将创建一个Company类来表示文本文件中的每一条公司记录。为了简洁,这里使用Lombok的@Getter和@Builder注解。

import lombok.Builder;
import lombok.Getter;

@Builder
@Getter
public class Company {
    private long id;
    private String street;
    private String locationDescription;
    private String companyName;
    private String state;
    private String country;
    private String zipCode;

    // 静态方法,用于将字符串行解析为Company对象
    public static Company parse(String line) {
        String[] arr = line.split(",");
        if (arr.length < 7) { // 简单校验数据完整性
            throw new IllegalArgumentException("Invalid line format: " + line);
        }
        return Company.builder()
            .id(Long.parseLong(arr[0]))
            .street(arr[1]) // 根据数据结构补充street字段
            .locationDescription(arr[2])
            .companyName(arr[3])
            .state(arr[4])
            .country(arr[5])
            .zipCode(arr[6])
            .build();
    }

    @Override
    public String toString() { // 方便打印
        return id + "," + street + "," + locationDescription + "," + companyName + "," + state + "," + country + "," + zipCode;
    }
}

注意: 原始数据中包含street字段,为了保证数据完整性,Company.parse()方法中已补充该字段的解析。

2. 使用领域对象进行去重

有了Company类后,我们可以先将每行字符串映射成Company对象,然后再利用Collectors.toMap以Company对象的id作为键进行去重。

import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

public class DuplicateCompanyRemover {

    public static void main(String[] args) {
        List sourceList = List.of(
            "123456,greenwitch street,near dominos store,Opp sandwitch company,Neyork,US,876890",
            "123480,Postwitch street,near KFC store,Opp masala company,Newyork,US,876891",
            "123456,Newyork street,near 100th avenue,King master company,Texas,US,10005"
        );

        List uniqueCompanies = sourceList.stream()
            .map(Company::parse)                           // 将每行字符串解析为Company对象
            .collect(Collectors.toMap(
                Company::getId,                            // keyMapper: 使用Company对象的ID作为键
                Function.identity(),                       // valueMapper: Company对象本身作为值
                (left, right) -> left                      // mergeFunction: 遇到重复ID时,保留第一个Company对象
            ))
            .values()
            .stream()
            .toList();

        System.out.println("\n去重后的列表 (Company对象方式):");

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

835

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

740

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

736

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

397

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

399

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

446

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

430

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

16926

2023.08.03

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

43

2026.01.16

热门下载

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

精品课程

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

共23课时 | 2.6万人学习

C# 教程
C# 教程

共94课时 | 6.9万人学习

Java 教程
Java 教程

共578课时 | 47.2万人学习

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

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