我想在我的应用程序中做的是,让用户使用filechooser选择一系列文本文件,然后我的应用程序将过滤其中一些不包含指定子字符串的文件。
这是我使用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 catesment包装它。
任何人都可以优雅地提出改进建议?
使用try with资源:
targetList.parallelStream()
.filter(f -> {
try (BufferedReader br = new BufferedReader(new FileReader(f))) {
return br.lines().anyMatch(line -> (line.contains(",")));
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
)
.collect(Collectors.toList());
您可以使用try with resources语句:
try-with-资源语句确保在语句末尾关闭每个资源。
targetList.parallelStream()
.filter(f -> {
try (BufferedReader br = new BufferedReader(new FileReader(f))) {
return br.lines().anyMatch(line -> (line.indexOf(",") != -1));
} catch (IOException e) {
e.printStackTrace();
}
return false;
})
.collect(Collectors.toList());
这可以用与本答案相同的技巧以优雅的方式解决。
可以创建一个应用函数的实用函数,然后使用try-with-resource-语句可靠地关闭资源。
使用该选项,您的代码将如下所示:
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);
}
}
使用这些您的代码将如下所示:
List<Path> filteredList = targetList.stream()
.filter(f -> Files.exists(f))
.filter(f -> applyAndClose(
() -> Files.lines(f),
lines -> lines.anyMatch(line-> line.contains(","))))
.collect(toList());
问题内容: 我认为这个问题已经存在,但是我找不到。 我不明白,为什么必须要有一个功能接口才能使用lambda。考虑以下示例: 这可以正常工作,但是如果您取消注释行,则不会。为什么?以我的理解,编译器应该能够区分这两种方法,因为它们具有不同的输入参数。为什么我需要一个功能接口并炸毁我的代码? 编辑:链接的重复项没有回答我的问题,因为我在询问不同的方法参数。但是在这里,我得到了一些非常有用的答案,这要
此函数返回值1或输入流中要读取的行数。 文件名作为函数的输入。 语法 (Syntax) lines(filename) 参数 (Parameters) filename - 这是文件的名称。 返回值 (Return Value) 此函数返回值1或输入流中要读取的行数。 例子 (Example) /* Main program */ do while lines(Example.txt) >
问题内容: Commons-IO有一种方法,可以从输入流中读取所有内容: 我的问题是使用后是否应手动关闭输入流? 我以为IOUtils可能会关闭它,因为它已读取所有内容,但是我在源代码中找不到它。 问题答案: Javadoc说: 只要有可能,此类中的方法就不会刷新或关闭流。这是为了避免对流的来源和进一步使用做出不可移植的假设。因此,调用方仍然负责在使用后关闭流。
对于接受文件输入的APIendpoint,我们需要手动关闭还是框架为我们这样做? 我查了新泽西的文件,但找不到任何关于它的信息。 寻找可靠的来源或某种方式来验证它。
有时,在处理流的两个步骤之间对流中的每个元素进行“处理”(例如打印)会很方便,例如调试。 一个简单的例子可能是这样的,不幸的是,这不起作用,因为消耗流: 如何做到这一点?
问题内容: 我有一个网站,它的点击率很高,我遇到了问题,JDCB连接错误。 我对关闭有点困惑,我需要关闭还是仅关闭就足够了。 另外,我需要关闭它吗? 问题答案: 是的,您必须关闭PreparedStatement和结果集,因为它们可能导致内存泄漏。有关更多信息,请访问 http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html