在Java中对txt文件进行排序的最佳方法

我有一个CSV文件,我正在使用opencsv库进行处理。 所以我可以阅读每一行。 我需要做的特定转换要求我在使用java文件的主要部分运行之前先对该文件进行排序。

例如

5423, blah2, blah 5323, blah3, blah 5423, blah4, blah 5444, blah5, blah 5423, blah6, blah 

应该成为

 5323, blah3, blah 5423, blah2, blah 5423, blah4, blah 5423, blah6, blah 5444, blah5, blah 

等等..

我需要这样做的原因是我将具有相同id的所有行组合并将它们输出到新文件。

有什么不对:

  1. 使用opencsv库读取csv的每一行

  2. 将它们添加到二维数组中

  3. 对此进行某种排序

  4. 循环排序数组并输出到文件。

关于此的任何其他想法以及对数据进行排序的最佳方法是什么?

我的Java上有点生锈。

更新:澄清最终输出

它看起来像:

 5323, blah3, blah 5423, blah2!!blah4!!blah6, blah 5444, blah5, blah 

这是我正在做的非常简化的版本。 实际上,JBase系统中的多选项字段需要它。 这是请求的文件格式。

原始文件中有超过100,000行。

这将不止一次运行,它运行的速度对我来说很重要。

为了完成最新的请求,我强烈建议在google集合中使用Multimap 。 您的代码如下所示:

 CSVReader reader = ...; CSVWriter writer = ...; Multimap results = TreeMultimap.create(); // read the file String[] line; for ((line = reader.readNext()) != null) { results.put(line[0], line[1]); } // output the file Map> mapView = results.asMap(); for (Map.Entry entry : mapView.entries()) { String[] nextLine = new String[2]; nextLine[0] = entry.getKey(); nextLine[1] = formatCollection(entry.getValue()); writer.writeNext(nextLine); } 

你需要使用"blah\n"作为你的行ender。 如果您关心速度,而不是关于对条目进行排序,那么您也应该对HashMultimap基准测试。

我以前的回答

最直接的方法是在* nix(例如Linux和Mac OS)中使用sort命令

 sort -n myfile.csv 

Windows也有一个sort命令,但会按字母顺序对行进行排序(即“5”,将放在“13”行之前)。

但是,建议的解决方案没有任何问题。 您也可以使用TreeSet ,而不是构造数组并对其进行排序。

编辑:添加关于Windows的注释。

如果您只对id的排序感兴趣,并且不关心该id中的排序,您可以简单地将Commons Collections的MultiValueMap与TreeMap结合起来:

 MultiValueMap m = MultiValueMap.decorate(new TreeMap()); m.put(2, "B"); m.put(3, "Y"); m.put(1, "F"); m.put(1, "E"); m.put(2, "K"); m.put(4, "Q"); m.put(3, "I"); m.put(1, "X"); for(Iterator iter = m.entrySet().iterator(); iter.hasNext(); ) { final Map.Entry entry = (Map.Entry)iter.next(); System.out.println(entry.getKey() + ": " + entry.getValue()); } 

运行这个给出:

 1: [F, E, X] 2: [B, K] 3: [Y, I] 4: [Q] 

有一个重载的decorate方法,它允许您指定要在MultiValueMap中使用的集合类型。 如果您需要在ID中进行排序,则可以对此执行某些操作。

您是否尝试过使用Collections.sort()Comparator实例?

您可以使用单个维度的ArrayList(或其他集合),并使用Collections排序方法对Java进行排序。 然而,你所描述的其他一切听起来都非常标准。

您说您需要“排序”这些项目,但您的描述听起来好像需要对它们进行分组 。 这可以通过多种方式完成; 您可能想要查看多个地图,例如Googlecollections集提供的地图; 或者你可以简单地创建一个

 HashMap> 

并在阅读时将每一行放入相关列表中。 我喜欢这样的情况是两次遍历文件,一次为每个键添加一个新的ArrayList,另一次将每个字符串添加到列表中,但是使用单个pass可能更有效(只是不那么简单) ,其中您检查列表是否已在地图中。

听起来你不需要对整个事情进行排序。 我不确定你会有多少行,但似乎你可以使用某种基于散列的方案。 您可以将文件视为散列映射中的存储桶,并在读取每一行后,确定它属于哪个文件。 然后,您可以进一步处理每个文件。 有几种方法可以做到这一点。

  • 如果你没有很多“密钥”,你实际上可以将所有密钥保存在内存中作为密钥在string => string的哈希映射中(将密钥映射到该行所属的文件名的映射)。

  • 如果有太多可能的密钥留在内存中。 您可以尝试将行存储到不同的文件中,以帮助减小文件的大小。 然后,您可以将每个文件保存在内存中,这样您就可以将行转储到集合中并进行排序。 或者可能使用我提到的第一个方案。

这有意义吗? 如果你感到困惑,我可以详细说明。 我想你的密钥将以某种方式组合你的csv行的所有列。

如果您的文件变得非常大,这种方法将更具可扩展性。 您不希望依赖于将整个文件放在内存中,并且排序需要O(nlogn)时间,而理论上,散列方案只是O(n)。

FlatPack非常适合阅读这样的文件并对其进行排序。 它还具有将数据集导出到文件的选项。