我有一个包含数千行单词的输入文本文件,我想在其中写入输出文件,并在其中反转每 10 行的顺序。我已经迭代了整个文本文件,并将其存储在
ArrayList<String> array
中,现在我正在尝试弄清楚如何反转整个 ArrayList 中每 10 行的顺序。
例如输出应该是这样的: Line : 10, 9, 8, 7 ...... 1, 20, 19, 18, 17.....11, 30, 29, 28, 27。 ....21 等等,直到我对整个文本文件(存储在 ArrayList 中)完成此操作。下面是我一直用来尝试反转这些行的代码部分。
for(int i = array.size()-1; i >= array.size()-10; i--){
array.add(array.get(i));
}
for (String text : array) {
w.println(text);
}
}
到目前为止,我仅读取并反转输入文件的最后 10 行,并将其写入输出文件。我一直在寻找一种方法来在整个数据集中迭代地实现这种类型的模式,以确保我不会遇到索引越界错误。
使用简单的流式传输方法。这基本上是当前的解决方案,每十行应用一次,而不是最后一次。
读十行。同样的流式处理方法可用于创建一个
neweach-10 反转列表。当尝试改变原始列表时,它只会“变得复杂”。
写入输出时,可以通过向后迭代十行列表来组合步骤 2 和 3。
如果它已在内存中,则在
ArrayList
List<String> list = new ArrayList<>();
// code filling list
for (int i = 0; i < list.size(); i += 10) {
int endOfBlock = Math.min(i + 10, list.size());
for (int j = i, k = endOfBlock - 1; j < k; j++, k--) {
String temp = list.get(j);
list.set(j, list.get(k));
list.set(k, temp);
}
}
选项 2。
try (BufferedReader in = new BufferedReader(new FileReader(inFile)),
PrintWriter out = new PrintWriter(new FileWriter(outFile))) {
String[] buf = new String[10];
int len = 0;
for (String line; (line = in.readLine()) != null; ) {
buf[len++] = line;
if (len == 10) {
while (len > 0)
out.println(buf[--len]);
}
}
while (len > 0)
out.println(buf[--len]);
}
for (int i = 0, size = array.size(); i < size; i += 10)
for (int from = i, to = Math.min(i + 10, size); from < to;)
Collections.swap(array, from++, --to);
while(counter<array.size()+10)
int counter = 9; //since index 9 is the 10th line
for(int i=counter; i>counter-10; i--){
if(i<array.size()){
array.add(array.get(i));
}
}
counter+=10;
}
for (String text : array){
w.println(text);
}
我在这里唯一担心的是,您似乎只是继续添加到现有数组,而不是重新排序或将元素添加到新数组?
Java 22 预览语言功能的基于流的解决方案:
// [1, 2, 3, ..., 21, 22]
List<String> lines = IntStream.range(1, 22).mapToObj(Integer::toString).toList();
// [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 22, 21]
List<String> output = list.stream()
.gather(Gatherers.windowFixed(10))
.flatMap(window -> window.reversed().stream())
.toList();
这使用新的
方法和新的内置
Gatherers.windowFixed
收集器将列表一次分为 10 个项目。演练
List<String>
Stream<String>
。
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]
lines.stream()
将元素收集到具有 10 个元素(或更少,如果位于流末尾)的窗口中。结果是 Stream<List<String>>
// [[1,2,3,4,5,6,7,8,9,10], [11,12,13,14,15,16,17,18,19,20], [21,22]]
.gather(Gatherers.windowFixed(10))
翻转每个窗口,然后将其压平。这将转换回 Stream<String>
// [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 22, 21]
.flatMap(window -> window.reversed().stream())
将 Stream<String>
List<String>
。
.toList()
:将输入元素流转换为输出元素流的中间操作,可以选择在到达上游末尾时应用最终操作。 […]
[…]
聚集操作的例子有很多,包括但不限于:将元素分组(窗口函数);对连续相似的元素进行去重;增量累加功能(前缀扫描);增量重新排序功能等。类
提供了常见收集操作的实现。
:返回一个流,其中包含将给定收集器应用于该流的元素的结果。
返回一个收集器,它将元素收集到固定大小的窗口中——遇到有序的元素组。如果流为空,则不会生成任何窗口。最后一个窗口包含的元素可能少于提供的窗口大小。
示例:
// will contain: [[1, 2, 3], [4, 5, 6], [7, 8]] List<List<Integer>> windows = Stream.of(1,2,3,4,5,6,7,8).gather(Gatherers.windowFixed(3)).toList();