【发布时间】:2022-01-04 14:06:44
【问题描述】:
在 Java 中,我有一个读取两个文件的方法,每行都是一个 GUID。行是无序的。输出是两个新文件,其中的行仅出现在每个文件上。
示例文件:
| Input_1 | Input_2 | | Output_1 | Output_2 |
| ------- | ------- | | -------- | -------- |
| abcdef | uvwxyz | > | mnopqr | uvwxyz |
| ghijkl | ghijkl |
| mnopqr | abcdef |
我设法为每个文件使用了一个 Collection<String> 和一些 addAll() + removeAll() 恶作剧,但文件的大小正在增长,这整个过程现在需要一些时间。每个文件大约有 600k 行。
是否有一种仅使用另一种类型的集合来改进此代码的快速方法,或者我需要重构我的工作方式?
有问题的代码:
//Read two files
Collection<String> guidFile1 = readFileGuid(pathFile1);
Collection<String> guidFile2 = readFileGuid(pathFile2);
//Add file1 and remove file2
Collection<String> leftFromFile1 = new ArrayList<String>();
leftFromFile1.addAll(guidFile1);
leftFromFile1.removeAll(guidFile2);
//Add file2 and remove file1
Collection<String> leftFromFile2 = new ArrayList<String>();
leftFromFile2.addAll(guidFile2);
leftFromFile2.removeAll(guidFile1);
//Outputs
System.out.println("Leftover from file1: " + leftFromFile1.size());
System.out.println("Leftover from file2: " + leftFromFile2.size());
【问题讨论】:
-
您为 Collection
接口使用了哪个实现?尝试 hashSet 而不是 List。 -
这个社区更多的是关于“不工作”的代码。您宁愿对性能方面进行审查,所以codereview.stackexchange.com 可能是一个更好的地方。话虽如此,这里有很多方面。例如:顺序重要吗?如果你使用 Set 对象而不是 Lists,section/intersection 会更有效率。但是,您可能会丢失文件中的顺序。长话短说:最佳解决方案取决于您的具体要求。
-
按顺序跟进:如果顺序无关紧要,您可以在从文件中读取列表后对列表进行排序。对 SORTED 内容进行这样的“增量”计算归结为以锁步方式迭代 2 个列表,仅一次,并避免例如调用
removeAll()两次的开销。另请注意:排序是您甚至可以在文件中读取的内容,例如使用一些命令行调整。因此,如前所述:有很多选择,但根据您的具体情况,它们都会有所不同。 -
如果文件无序,我会说您需要在文件 1 中创建一组 guid,然后检查文件 2 中存在哪些(您可以在此处使用流)。一种简单的方法是为文件 1 构建整个集合,然后处理文件 2。如果文件具有相似的顺序,您还可以尝试更复杂的方法,并行读取文件(例如较小的批次),但这可能会变得非常复杂.
-
@GhostCat 您对网站的看法完全正确,现在我感到有些羞耻。我不需要订单,只需要线条。这些文件一开始是无序的。
标签: java performance collections add removeall