每个函数之后的 Java 流串联

标签 java java-8 java-stream

当我们使用Stream.concat连接流时,是否可以在流结束时运行一个函数?

例如

我正在使用 Files.lines 从多个文件创建流。现在,每当一个文件被完全读取时,我就需要将其删除。

最佳答案

通过Stream.concat组成的流的关闭处理程序在结果流关闭时执行。请注意,关闭处理程序通常要求使用流的代码关闭流,例如

try(Stream<String> s=Stream.concat(Files.lines(path1), Files.lines(path2))) {
    s.forEach(System.out::println);
}

正确关闭和

try(Stream<String> s=Stream.concat(
        Files.lines(path1).onClose(()->{
            try { Files.delete(path1); }
            catch (IOException ex) { throw new UncheckedIOException(ex); }
        }),
        Files.lines(path2).onClose(()->{
            try { Files.delete(path2); }
            catch (IOException ex) { throw new UncheckedIOException(ex); }
        }))
    ) {

    s.forEach(System.out::println);
}

用于随后删除文件。但在这种情况下,结果流的关闭处理程序将调用源流的关闭处理程序,因此这不会在使用后立即删除文件,而是在整个操作之后删除,因此与

try(Closeable c1=() -> Files.deleteIfExists(path1);
    Closeable c2=() -> Files.deleteIfExists(path2);
    Stream<String> s=Stream.concat(Files.lines(path1), Files.lines(path2)); ) {

    s.forEach(System.out::println);
}

如果你想及时删除文件,你必须使用flatMap。无论“外”流是否关闭,子流在使用后都会立即关闭:

Stream.of(path1, path2)
      .flatMap(path -> {
            try { return Files.lines(path).onClose(()->{
                try { Files.delete(path); }
                catch (IOException ex) { throw new UncheckedIOException(ex); }
            }); }
            catch (IOException ex) { throw new UncheckedIOException(ex); }
        })
       .forEach(System.out::println);
<小时/>

为了证明差异,

try(Stream<String> s=Stream.concat(
        Stream.of("foo").onClose(()->System.out.println("foo closed")),
        Stream.of("bar").onClose(()->System.out.println("bar closed")) )) {
    s.forEach(System.out::println);
}

将打印

foo
bar
foo closed
bar closed

Stream.of("foo", "bar")
    .flatMap(x -> Stream.of(x).onClose(()->System.out.println(x+" closed")) )
    .forEach(System.out::println);

将打印

foo
foo closed
bar
bar closed

关于每个函数之后的 Java 流串联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40629620/

相关文章:

Java 将两个 double[][] 与并行流相加

java - 如何在android中使用GreenDao为数据库添加初始数据?

java - 使用 JPA 的 Hibernate 4.3 SchemaUpdate

java - SWT获取光标位置

java - Java 8 中的功能接口(interface)(方法执行时间记录器)

java 8根据属性比较2个列表

java - Collectors.toMap() 中的错误报告是否已损坏?

java - 常见的 AVD 模拟器已在运行错误

Java 8 : Supplier working with files throws "stream has already been operated upon or closed"

java - 如何将以下方法转换为 Java 8 内联函数?