我有要排序并合并到输出文件中的已排序 csv 文件列表。
我不想对字符串进行简单的比较,而是根据我对每个值的类型映射进行相应的比较,例如:
其中一行:
1, 15/12/2011,大卫·雷文,纽约
在类型映射中,我有这个:第一列 - 长,第二列 - 日期,第三列字符串,...
因此比较器应该相应地比较值。
怎样才能以最高效率做到这一点?
优先队列?树形图?
我不想使用第三方库或排序器。
输入文件非常巨大。
最佳答案
创建一个 Readers/InputStream 数组(或者,如果您愿意,可以创建一个集合),每个 CSV 文件对应一个。
与@JustinKSU的想法类似,创建一个TreeMap,其中键是CSV文件中的一行。传递一个自定义比较器,您的自定义实现,按长、日期等排序。该值是数组/集合中哪个文件的索引(可能是整数,如果您的集合是映射,则可能是文件名)。
通过读取每个文件的第一行来为 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...
}
}
关于java - 通过复杂比较合并多个排序的 csv 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8593219/