Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java流生命周期回调_Java_Java Stream - Fatal编程技术网

Java流生命周期回调

Java流生命周期回调,java,java-stream,Java,Java Stream,当流的最后一个元素被处理并且流被完全“消耗”时,是否存在一种优雅的方法来注册回调 尤其是当流源(如DB游标、迭代器或自定义供应商)是有限的,并且可以明确知道何时没有更多数据时 例如: public Stream<Row> query(String sql){ Connection c = dataSource.openConnection(); Stream<Row> rows = MyDB.query(sql).stream(); c.close();

当流的最后一个元素被处理并且流被完全“消耗”时,是否存在一种优雅的方法来注册回调

尤其是当流源(如DB游标、
迭代器或自定义
供应商
)是有限的,并且可以明确知道何时没有更多数据时

例如:

public Stream<Row> query(String sql){
   Connection c = dataSource.openConnection();
   Stream<Row> rows = MyDB.query(sql).stream();
   c.close();
   return rows;
}
公共流查询(字符串sql){
连接c=dataSource.openConnection();
Stream rows=MyDB.query(sql.Stream();
c、 close();
返回行;
}
现在,立即关闭连接是徒劳的,相反,在流被完全消耗时安排关闭连接会更好

我知道有
onClose()
API,但这依赖于用户在流上显式调用
close()

您想注册一个:

公共流查询(字符串sql){
连接c=dataSource.openConnection();
返回MyDB.query(sql.stream().onClose(()->c.close());
}
此方法的调用方必须异常地关闭流

(注意:我在这里遗漏了异常处理。)

调用,并记录调用者必须关闭返回的流

/**
 * The returned stream must be closed.
 */
public Stream<Row> query(String sql){
    Connection c = dataSource.openConnection();
    return MyDB.query(sql).stream().onClose(() -> {
        try {
            c.close();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    });
}
/**
*必须关闭返回的流。
*/
公共流查询(字符串sql){
连接c=dataSource.openConnection();
返回MyDB.query(sql).stream().onClose(()->{
试一试{
c、 close();
}捕获(SQLE异常){
抛出新的运行时异常(e);
}
});
}

一种主要工作的实用程序,除非返回的流没有迭代到底:

public <T> Stream<T> wrap(Stream<T> stream, Runnable onEnd) {
    final Object endSignal = new Object();
    return Stream.concat(stream, Stream.of(endSignal))
            .peek(i -> {
                if(i == endSignal){onEnd.run();}
            })
            .filter(i -> i != endSignal)
            .map(i -> (T) i);
}
public Stream wrap(Stream-Stream,Runnable-oned){
最终对象endSignal=新对象();
返回流concat(流,流of(endSignal))
.peek(i->{
如果(i==endSignal){onEnd.run();}
})
.filter(i->i!=结束信号)
.map(i->(T)i);
}

这是否意味着流的使用者必须显式地调用流上的
close()
?例如,假设流是以
迭代器作为源构建的。所以,当源
迭代器
hasNext()
返回
false
?@s.D.是的,调用方必须调用close,或者使用try with resources,就像调用方在任何其他资源绑定流上所需做的一样,比如返回的那些流。没有自动的“流用完”回调,因为流可能永远不会用完。@ernest_k,因为终端操作可能不会完全使用流。假设您有一个名为
s
的流,以及以下代码:
s.limit(10).forEach(…)
。这只消耗前10个值,因此您可以执行其他操作来处理其余的值。只有你自己才能确定何时处理完流,因此关闭流是你的责任。@Andreas你知道允许“处理其余部分”的实际流源吗?@Slaw我想,语言是那么弱,因为
stream
是一个接口。当您尝试多次使用引用实现时,它将引发异常。另一种可能是可以返回新流的源,但是,不能保证流只从源中获取这些元素,它在概念上会消耗,特别是并行流会进行预取。例如,
BufferedReader
明确表示,一旦处理了它的
lines()
流,它就处于未定义状态。所以这里没有“处理其余的”。我不知道有什么反例。
public <T> Stream<T> wrap(Stream<T> stream, Runnable onEnd) {
    final Object endSignal = new Object();
    return Stream.concat(stream, Stream.of(endSignal))
            .peek(i -> {
                if(i == endSignal){onEnd.run();}
            })
            .filter(i -> i != endSignal)
            .map(i -> (T) i);
}