我试图了解在Java集合中对file.txt行进行排序的最佳方法。
使用orderedSet删除重复,我不想要那样。
PriorityQueue完成这项工作,但我需要我的课程是可以使用的,并且使用PriorityQueue.Iterator不会给出排序结果。
现在我对使用Arrays.sort或采用这种方法感到困惑: 在从文本中读取行时使用PriorityQueue然后复制数组上的最终队列以使用其迭代器?
public class FileSorter implements Iterable<String> {
// this sorted set contains the lines
private PriorityQueue<String> lines0 = new PriorityQueue<>() ;
private ArrayList<String> lines = new ArrayList<>();
public void readFiles (String[] filePaths) throws IOException {
BufferedReader buf = null;
String line ;
for (String path:filePaths) {
//opening the file
buf = new BufferedReader(new FileReader(new File(path)));
//iterating through the lines and adding them the collection
while ((line = buf.readLine()) != null) {
if(line.trim().length() > 0) { //no blank lines
lines0.add(line);
}
}
};
//closing the buffer
buf.close();
while (!lines0.isEmpty()){
lines.add(lines0.poll());
}
}
public Iterator<String> iterator() {
return lines.iterator();
}
}
谢谢。
答案 0 :(得分:1)
我认为实施Iterable
并不是最好的方法,因为你应该更喜欢构图而不是继承,毕竟它是2017年;没有人再实现自己的集合类了。那说,下面怎么样?
public class Main {
public static void main(String[] args) throws IOException, URISyntaxException {
for (String line : new FileSorter(new File(Main.class.getResource("test.txt").toURI()).toPath())) {
System.out.println(line);
}
}
static class FileSorter implements Iterable<String> {
private final Path path;
FileSorter(Path path) {
this.path = path;
}
@Override
public Iterator<String> iterator() {
try {
return Files.lines(path)
.sorted()
.iterator();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
}
在与test.txt
类相同的目录中给出文件Main
:
a
b
a
c
以上程序打印:
a
a
b
c
Iterable
具有与Stream
不同的语义,因为前者可以重复使用,而后者只能使用一次(直到终端操作)。因此,每次调用iterator()
时,我的实现都会读取文件。我没有尝试优化它,因为你没有要求它,过早的优化是所有邪恶的根源。