我正在制作一个涉及读取文本文件 (.txt) 的应用程序,其中一个要求是在文件中保留 N(其中 N 由用户指定)最长的行,同时保持它们的顺序出现在文件中。
因此,例如,如果一个文件有 10 行且 N = 4,则文件中最长的 4 行将被保留,而所有其他行将被删除。完成此操作时要保持它们在文件中出现的顺序。
我使用 LinkedHashMap 将行的内容存储为键,将行的长度存储为值。
LinkedHashMap<String, Integer> linesInFile = new LinkedHashMap<String, Integer>();
String line = "";
String newFileContent = "";
try {
FileReader fileReader = new FileReader(file);
BufferedReader br = new BufferedReader(fileReader);
while ((line = br.readLine()) != null) {
linesInFile.put(line, line.length());
}
br.close();
List<Entry<String, Integer>> lineList = new ArrayList<Entry<String, Integer>>(linesInFile.entrySet());
List<Entry<String, Integer>> lineOrder = new ArrayList<Entry<String, Integer>>(linesInFile.entrySet());
Collections.sort(lineList, (e1, e2) -> (e2.getValue() - e1.getValue()));
int i = 0;
while (N > 0) {
newFileContent += lineList.get(i).getKey() + System.lineSeparator();
i++;
N--;
}
} catch (Exception e) {
// do something
}
上面的问题是它不保留文件中行的顺序。如何保留行出现的顺序?
例如,如果我有以下文件
Log: 123 abc
Error: 456123123 123 xyz
Log: 456 cde
Log: 1231 cde
Error: 123123 ab c
Error: 456123 123 xyz
Log: 123 cde
Error: 456 123 qrz
Error: 123 123 xyz
Log: 456 cde
Log: 456 cde
如果我保留文件中最长的 4 行,则更改后的文件将是
Error: 456123123 123 xyz
Error: 123123 ab c
Error: 456123 123 xyz
Error: 456 123 qrz
最佳答案
如果处理文件后可以恢复原始顺序:
- 创建一个类来保存行(字符串)及其行号,将其命名为
Line
。 - 创建
PriorityQueue
持有Line
,其中Comparator
比较Line
的两个实例并返回最短线是最少(请参阅Comparator
的接口(interface),了解您必须在那里实现的内容)。 - 一次一行读取文件,将每一行放入其自己的
Line
中,并将其放入优先级队列中。每次优先级队列的大小超过N
时,都会删除一个项目 - 它将是最小的项目(根据优先级队列的定义),并且将是集合中最短的行(根据比较器的定义) )。因此优先级队列将保留最长的N
行。 - 读完文件后,您的优先级队列中将有(最多)
N
个项目。根据它们的原始行号对它们进行排序(当然,为了这个目的,保留在Line
中),然后就到了。
这对于优先级队列来说绝对是理想的应用程序 - 一个已经为您实现的很好的数据结构。您需要做的就是创建正确的比较器来运行它(如上所述),并创建另一个用于对原始行号进行排序的比较器,然后就完成了。
关于java - 如何保留文件中最长的行,同时保持它们出现的顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57226704/