合并多个排序的csv文件与复杂的比较

时间:2011-12-21 16:40:50

标签: java sorting merge io

我有要排序并合并到输出文件中的已排序,csv文件列表。

我不想对字符串进行简单的比较,而是根据每个值的类型映射进行比较,例如:

其中一条线:
1,15 / 12/2011,David Raiven,纽约

在类型图中我有这个:第一列 - 长,第二日,第三串,......

因此比较器应相应地比较值。

我怎样才能以最高的效率做到这一点? 的PriorityQueue? TreeMap的?

我不想使用第三方图书馆或分拣机 输入文件非常庞大。

3 个答案:

答案 0 :(得分:1)

为Readers / InputStreams创建一个数组(或者,如果您愿意,还有一个Collection),每个CSV文件一个。

与@JustinKSU想法类似,创建一个TreeMap,其中键是CSV文件中的一行。传递一个自定义比较器,你的自定义impl,按长,日期等排序。值是你的数组/集合中哪个文件的索引(可能是一个整数,可能是你的Collection是一个Map的文件名)。

通过读取每个文件的第一行来播种TreeMap。

使用TreeMap.pollFirstEntry()删除最低行,并将键(行)写入Writer / OutputStream。使用该值从相应的文件中读取另一行(检查EOF)并将其添加到TreeMap中。

重复直到TreeMap为空。关闭一切。

编辑 - 在

下添加源代码

注意,仅当输入文件已经排序时才有效! (如问题中所述)

public void mergeSort(File[] inFiles, File outFile, Comparator<String> comparator) throws IOException  {

      try {
         BufferedReader[] readers = new BufferedReader[inFiles.length];
         PrintWriter writer = new PrintWriter(outFile);
         TreeMap<String, Integer> treeMap = new TreeMap<String, Integer>(
               comparator);

         // read first line of each file. We don't check for EOF here, probably should
         for (int i = 0; i < inFiles.length; i++) {
            readers[i] = new BufferedReader(new FileReader(inFiles[i]));
            String line = readers[i].readLine();
            treeMap.put(line, Integer.valueOf(i));
         }

         while (!treeMap.isEmpty()) {
            Map.Entry<String, Integer> nextToGo = treeMap.pollFirstEntry();
            int fileIndex = nextToGo.getValue().intValue();
            writer.println(nextToGo.getKey());

            String line = readers[fileIndex].readLine();
            if (line != null)
               treeMap.put(line, Integer.valueOf(fileIndex));
         }
      }
      finally {
         // close everything here...
      }
   }

答案 1 :(得分:0)

如果您想在内存中完成所有操作,我建议您在比较器中传递一个TreeSet。这将是最简单的实施。如果你不能将它全部存储在内存中,你可以打开所有文件的InputStreams并循环,直到你确定“最低”值并将其输出到你的新文件。

答案 2 :(得分:0)

一个,也许有点非正统的选择,是使用动态数据库,例如HSQLDB。在具有足够空间的临时目录中的某个位置打开数据库,使用所需字段创建表,插入所有CSV文件中的所有记录,最后从具有反映所需的ORDER BY子句的所有记录中进行选择排序顺序并将结果保存在您想要的位置。当然这需要一些磁盘空间,但它是我过去用于类似问题的可能解决方案。