gpt4 book ai didi

java - 使用 lines() stream Lambda 但需要关闭

转载 作者:行者123 更新时间:2023-11-29 06:52:37 26 4
gpt4 key购买 nike

我想在我的应用程序中做的是让用户使用文件选择器选择一系列文本文件,然后如果它不包含指定的子字符串,我的应用程序将过滤其中的一些。

这是我使用 lambda 的代码:

    FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("choose files");
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("TXT files (*.txt)", "*.txt"));
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("CSV files (*.csv)", "*.csv"));
List<File> targetList = fileChooser.showOpenMultipleDialog(primaryStage);
if (targetList == null) {
System.out.println("targetList none");
}
targetList.parallelStream()
.filter(f->{
try {
return new BufferedReader(new FileReader(f)).lines()
.anyMatch(line-> (line.indexOf(",")!=-1));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return false;
}
)
.collect(Collectors.toList());

它有效,但并不完美!因为 BufferedReader 永远不会关闭,所以我需要用 Buiky catch 语句包装它。

任何人都可以提供提示以优雅的方式改进它吗?

最佳答案

这可以使用与 this answer 中相同的技术以优雅的方式解决。 .

可以使用 try-with-resource-statement 创建一个应用函数然后可靠地关闭资源的实用函数。

使用它,您的代码将如下所示:

List<File> filteredList = targetList.parallelStream()
.filter(f -> f.exists())
.filter(f -> applyAndClose(
() -> new BufferedReader(new FileReader(f)),
reader -> reader.lines().anyMatch(line-> (line.indexOf(",") !=-1))))
.collect(Collectors.toList());

请注意,您必须保存 collect 方法的结果,否则会丢失!此外,我在单独的步骤中测试文件是否存在。

效用函数本身如下所示:

/**
* Applies a function to a resource and closes it afterwards.
* @param sup Supplier of the resource that should be closed
* @param op operation that should be performed on the resource before it is closed
* @return The result of calling op.apply on the resource
*/
public static <A extends AutoCloseable, B> B applyAndClose(Callable<A> sup, Function<A, B> op) {
try (A res = sup.call()) {
return op.apply(res);
} catch (RuntimeException exc) {
throw exc;
} catch (Exception exc) {
throw new RuntimeException("Wrapped in applyAndClose", exc);
}
}

其他改进

  • java.io.File 类和相关 API 大部分已过时。自 Java 7 以来,处理文件的标准方法是 java.nio.file.PathFiles 类。
  • 使用 String.contains 而不是 indexOf
  • toList 使用静态导入:import static java.util.stream.Collectors.toList;
  • 如果您要处理至少数百个文件,使用并行流可能会更快。

使用这些你的代码将如下所示:

List<Path> filteredList = targetList.stream()
.filter(f -> Files.exists(f))
.filter(f -> applyAndClose(
() -> Files.lines(f),
lines -> lines.anyMatch(line-> line.contains(","))))
.collect(toList());

关于java - 使用 lines() stream Lambda 但需要关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42665698/

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