
本教程详细阐述了在java中如何高效地从文本数据中删除基于首字段重复的整行记录。文章提供了两种核心策略:一是利用java stream api的`collectors.tomap`直接处理字符串列表,通过自定义键映射和合并函数实现去重;二是引入领域对象(如`company`类)来封装数据,提高代码可读性和可维护性,并结合stream api进行去重。教程包含示例代码、注意事项及最佳实践,旨在帮助开发者选择合适的去重方案。
在处理文本数据时,经常会遇到需要根据记录中的特定字段来识别并删除重复行的情况。例如,在一个包含公司信息的文本文件中,我们可能希望根据公司的唯一标识符(如ID)来确保每家公司只保留一条记录,即使其他字段有所不同。本教程将探讨两种在Java中实现这一目标的有效方法。
当数据以字符串列表的形式存在时,我们可以利用Java 8引入的Stream API及其强大的Collectors.toMap()方法来实现基于首字段的去重。这种方法简洁高效,适用于快速处理。
Collectors.toMap()允许我们指定如何从流中的元素生成键(keyMapper)和值(valueMapper)。更重要的是,它提供了一个mergeFunction来处理当多个元素生成相同的键时如何合并这些值。通过将行的第一个字段作为键,整行作为值,并指定在键冲突时保留第一个遇到的值,即可实现去重。
假设我们有一个包含公司信息的字符串列表,每行以逗号分隔,第一个字段是公司ID。
立即学习“Java免费学习笔记(深入)”;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
public class DuplicateRowRemover {
public static void main(String[] args) {
List<String> 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<String> uniqueList = sourceList.stream()
.collect(Collectors.toMap(
str -> str.substring(0, str.indexOf(',')), // keyMapper: 提取第一个逗号前的子字符串作为键
Function.identity(), // valueMapper: 整行字符串作为值
(existing, replacement) -> existing // mergeFunction: 当键重复时,保留已存在的(即第一个遇到的)值
))
.values() // 获取Map中所有的值(即去重后的行)
.stream()
.toList(); // 转换为List
System.out.println("去重后的字符串列表:");
uniqueList.forEach(System.out::println);
// 预期输出:
// 123456,greenwitch street,near dominos store,Opp sandwitch company,Neyork,US,876890
// 123480,Postwitch street,near KFC store,Opp masala company,Newyork,US,876891
}
}在上述代码中:
尽管直接处理字符串列表对于简单场景很有效,但在更复杂的应用中,将文本数据解析成具体的领域对象(如Company类)会大大提高代码的可读性、可维护性和类型安全性。
首先,定义一个POJO(Plain Old Java Object)来表示文本文件中的每一行数据。为了简洁,这里使用Lombok的@Getter和@Builder注解,但也可以使用标准的Java Getter和构造器。
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]) // 假设所有字段都有用
.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;
}
}有了Company对象后,我们可以先将字符串列表映射成Company对象的流,然后再使用Collectors.toMap()进行去重。
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
public class CompanyDuplicateRemover {
public static void main(String[] args) {
List<String> 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<Company> uniqueCompanies = sourceList.stream()
.map(Company::parse) // 将每行字符串解析为Company对象
.collect(Collectors.toMap(
Company::getId, // keyMapper: 使用Company对象的ID作为键
Function.identity(), // valueMapper: Company对象本身作为值
(existing, replacement) -> existing // mergeFunction: 当ID重复时,保留已存在的Company对象
))
.values() // 获取Map中所有的Company对象
.stream()
.toList(); // 转换为List
System.out.println("去重后的Company对象列表:");
uniqueCompanies.forEach(System.out::println);
// 预期输出 (Company的toString方法):
// 123456,greenwitch street,near dominos store,Opp sandwitch company,Neyork,US,876890
// 123480,Postwitch street,near KFC store,Opp masala company,Newyork,US,876891
}
}这种方法的核心优势在于:
// 示例:从文件读取
// List<String> allLines = Files.readAllLines(Paths.get("your_file.txt"), StandardCharsets.UTF_8);
//
// 示例:写入文件
// Files.write(Paths.get("unique_records.txt"), uniqueList, StandardCharsets.UTF_8);本文介绍了在Java中根据文本数据首字段删除重复行的两种主要方法:直接使用Stream API的Collectors.toMap()处理字符串,以及通过引入领域对象来提高代码质量。选择哪种方法取决于您的具体需求:对于简单的、一次性的任务,直接处理字符串可能更快捷;而对于需要长期维护、业务逻辑复杂的应用,使用领域对象无疑是更健壮、更可维护的方案。无论选择哪种方法,都应充分考虑错误处理、性能优化和业务逻辑中对重复项的保留策略。
以上就是Java中根据首字段删除文本数据重复行的策略与实现的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号