使用 Java 删除文件中的重复行

2022-09-01 16:26:48

作为我正在处理的项目的一部分,我想清理我生成的重复行条目的文件。但是,这些重复项通常不会彼此靠近发生。我想出了一种在Java中这样做的方法(它基本上是制作文件的副本,然后使用嵌套的while语句将一个文件中的每一行与另一个文件的其余部分进行比较)。问题是,我生成的文件非常大,文本很重(大约225k行文本,大约40兆克)。我估计我目前的流程需要63个小时!这绝对不可接受。

但是,我需要一个集成的解决方案。最好是Java。有什么想法吗?谢谢!


答案 1

嗯。。。40兆似乎足够小,你可以构建一个行,然后把它们全部打印出来。这将比执行O(n2)I / O工作快得多。Set

它将是这样的(忽略例外):

public void stripDuplicatesFromFile(String filename) {
    BufferedReader reader = new BufferedReader(new FileReader(filename));
    Set<String> lines = new HashSet<String>(10000); // maybe should be bigger
    String line;
    while ((line = reader.readLine()) != null) {
        lines.add(line);
    }
    reader.close();
    BufferedWriter writer = new BufferedWriter(new FileWriter(filename));
    for (String unique : lines) {
        writer.write(unique);
        writer.newLine();
    }
    writer.close();
}

如果顺序很重要,则可以使用 而不是 .由于元素是通过引用存储的,因此与实际数据量相比,额外链表的开销应该微不足道。LinkedHashSetHashSet

编辑:正如Shopning Alex所指出的,如果您不介意制作临时文件,则可以在阅读时简单地打印出行。这允许您使用简单而不是 .但我怀疑您是否会注意到像这样的I / O绑定操作的差异。HashSetLinkedHashSet


答案 2

好吧,大多数答案都有点愚蠢和缓慢,因为它涉及向某个哈希集或其他任何内容添加行,然后再次将其从该集合移回。让我展示伪代码中最优化的解决方案:

Create a hashset for just strings.
Open the input file.
Open the output file.
while not EOF(input)
  Read Line.
  If not(Line in hashSet)
    Add Line to hashset.
    Write Line to output.
  End If.
End While.
Free hashset.
Close input.
Close output.

拜托伙计们,不要让它变得比它需要的更困难。:-)甚至不要费心排序,你不需要。