Java实现文本文件重复项Count列求和的技术咨询
问题分析与解决方案
看起来你是想针对文本文件中的重复项(按RunID或自定义标识)对Count列数值求和,但现有代码的逻辑绕了弯路,既没正确判断重复项,也没实现累加逻辑。我来帮你梳理问题,再给出清晰的实现方案。
你现有代码的核心问题
- 逻辑混乱:用两个HashSet判断重复,但没有存储累加的Count值;
testt的处理完全无效——循环赋值name却从未使用,导致后续的重复判断都是空架子。 - 空值判断错误:
data[2].equals(null)会直接抛出NullPointerException,正确写法应该是Objects.isNull(data[2])或data[2] == null。 - 资源泄漏风险:Scanner未用try-with-resources自动关闭,异常场景下可能导致资源无法释放。
- 缺失累加逻辑:从头到尾没有对Count值做累加操作,仅打印了原始数值。
正确实现思路
核心是用HashMap存储分组键(比如RunID、RunID+Segment,或你需要的文件名子串)和对应的Count总和。步骤如下:
- 读取文件并跳过表头行;
- 逐行分割数据,提取分组键和Count值;
- 用HashMap维护累加:键存在则累加Count,不存在则初始化存入;
- 处理完所有行后,输出最终的求和结果。
完整可运行代码
import java.io.File; import java.io.FileNotFoundException; import java.util.HashMap; import java.util.Map; import java.util.Objects; import java.util.Scanner; public class CountSumProcessor { public static void main(String[] args) { // 替换为你的目标目录路径 String directoryPath = "your/target/directory"; File directory = new File(directoryPath); File[] filesList = directory.listFiles(); if (filesList == null) { System.out.println("指定目录不存在或无法访问"); return; } // HashMap:键=分组标识(这里用RunID),值=对应Count的总和 Map<String, Long> countSumMap = new HashMap<>(); for (File file : filesList) { String filename = file.getName(); if (!filename.endsWith(".txt")) { continue; } // try-with-resources自动关闭Scanner,避免资源泄漏 try (Scanner sc = new Scanner(file)) { // 跳过表头行 if (sc.hasNextLine()) { sc.nextLine(); } while (sc.hasNextLine()) { String input = sc.nextLine().trim(); if (input.isEmpty()) { continue; } // 按|分割数据,限制为4个字段(避免文件名含|的情况) String[] data = input.split("\\|", 4); if (data.length < 4) { System.out.println("无效行(字段不足):" + input); continue; } String runId = data[0].trim(); String countStr = data[2].trim(); // 校验空值 if (Objects.isNull(runId) || runId.isEmpty() || Objects.isNull(countStr) || countStr.isEmpty()) { System.out.println("无效行(RunID/Count为空):" + input); continue; } // 转换Count为long(避免大数值溢出int) long count; try { count = Long.parseLong(countStr); } catch (NumberFormatException e) { System.out.println("无效Count数值:" + countStr + ",行内容:" + input); continue; } // 累加Count到对应分组 countSumMap.put(runId, countSumMap.getOrDefault(runId, 0L) + count); } } catch (FileNotFoundException e) { System.err.println("文件未找到:" + file.getAbsolutePath()); e.printStackTrace(); } } // 输出最终结果 System.out.println("===== 分组Count求和结果 ====="); for (Map.Entry<String, Long> entry : countSumMap.entrySet()) { System.out.println("RunID: " + entry.getKey() + " | 总Count: " + entry.getValue()); } } }
关键细节说明
- 灵活分组:如果需要按其他维度分组(比如RunID+Segment,或你之前想提取的文件名子串),只需修改键的生成逻辑:
- 按RunID+Segment分组:
String key = data[0].trim() + "|" + data[1].trim(); - 按文件名子串(两个下划线之间的部分)分组:
String fileName = data[3].trim(); int firstUnderscore = fileName.indexOf("_"); int secondUnderscore = fileName.indexOf("_", firstUnderscore + 1); int lastUnderscore = fileName.lastIndexOf("_"); if (firstUnderscore != -1 && secondUnderscore != -1 && lastUnderscore != -1) { String fileTag = fileName.substring(secondUnderscore + 1, lastUnderscore); String key = data[0].trim() + "|" + fileTag; }
- 按RunID+Segment分组:
- 数据校验:增加了字段长度、空值、数字格式的校验,避免脏数据导致程序崩溃;
- 资源安全:用try-with-resources自动管理Scanner,无需手动关闭。
运行你的示例数据后,会得到符合预期的求和结果,比如RunID 6230的总Count为292088+1000000+1000000+1000000=3292088。
内容的提问来源于stack exchange,提问作者Punksnation
相关产品推荐
相关产品推荐

