gpt4 book ai didi

Java:使用 lambda 向文件添加行号的优雅方式

转载 作者:搜寻专家 更新时间:2023-11-01 01:50:19 25 4
gpt4 key购买 nike

很长一段时间以来,我习惯于使用 lambda 逐行解析文件(比 bufferedReader.readLine() 简洁得多)。但是今天我遇到了一个问题:为每一行添加一个行号。

它需要一个计数器,但 lambda 中的变量应该是有效的最终变量。最后,我用一个 int 数组破解了它。

代码:

public static void main(String[] args) {
int[] counter = new int[1];
counter[0] = 0;
try (Stream<String> lines = Files.lines(Paths.get("/tmp/timeline.txt"), Charset.defaultCharset())) {
lines.limit(10).forEachOrdered(line -> {
line = line.trim();
counter[0] ++;
System.out.println("Line " + counter[0] + ": " + line);
});
} catch (IOException e) {
e.printStackTrace();
}
}

输出:

Line 1: p 5714026 wEkQ
Line 2: v 8235889
Line 3: v 6534726
...

我的问题是,如何避免我的 hack 并优雅地解决该问题?

最佳答案

对于非功能性任务,没有优雅的功能性解决方案。您可能首先考虑的是诉诸普通的匿名内部类:

String path = "/tmp/timeline.txt";
try(Stream<String> lines = Files.lines(Paths.get(path), Charset.defaultCharset())) {
lines.limit(10).forEachOrdered(new Consumer<String>() {
int counter = 0;
public void accept(String line) {
System.out.println("Line " + counter++ + ": " + line.trim());
}
});
} catch (IOException e) {
e.printStackTrace();
}

优点是它不会假装在没有功能的地方发挥作用,并且 counter 变量的范围具有此任务所需的最小范围。


如果您要做的不仅仅是打印这些编号的行,并且需要一个与所有流操作兼容的解决方案,那么重新实现流源是一个直接的解决方案:

static Stream<String> numberedLines(Path path, Charset cs) throws IOException {
BufferedReader br = Files.newBufferedReader(path, cs);
return StreamSupport.stream(new Spliterators.AbstractSpliterator<String>(
Long.MAX_VALUE, Spliterator.ORDERED|Spliterator.NONNULL) {
int counter;
public boolean tryAdvance(Consumer<? super String> action) {
String line;
try {
line = br.readLine();
if(line==null) return false;
action.accept("Line " + counter++ + ": " + line.trim());
return true;
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}
}, true).onClose(()->{ try { br.close(); }
catch (IOException ex) { throw new UncheckedIOException(ex); }
});
}

当然,这不像单个 lambda 表达式那么简单,但使用这种可重用的方法,您可以毫无问题地使用所有流操作,例如

String path = "/tmp/timeline.txt";
try(Stream<String> lines = numberedLines(Paths.get(path), Charset.defaultCharset())) {
lines.skip(10).limit(10).forEachOrdered(System.out::println);
} catch(IOException e) {
e.printStackTrace();
}

关于Java:使用 lambda 向文件添加行号的优雅方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36478579/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com