我有一个管理Stream
的类:
class MyStreamManager {
private Stream<Object> currentStream = null;
boolean hasMoreData() {
//code here to assert currentStream is null
final Optional<Stream<Object>> maybeAStream = somethingWhichMightProvideAStream.getNextStream();
currentStream = maybeAStream.orElse(null);
return currentStream != null;
}
@MustBeClosed
Stream<Object> getCurrentStream() { return currentStream; }
void finish() {
currentStream.close();
currentStream = null;
}
}
使用以下样式:
while (myStreamManager.hasMoreData()) {
try {
myStreamManager.getCurrentStream().map(...).filter(...); //etc
} finally {
myStreamManager.finish();
}
}
是否正在存储对Stream的引用,例如这种不良做法?虽然这样做有效,但绝对感觉不对,并且ErrorProne正在对其进行标记(因此带有@MustBeClosed
注释)。
MyStreamManager
是Spring @Bean
,但仅由一个线程使用(该线程正在批量运行)。
我可以想到两种可能更好的不同方法:
MyStreamManager
并将其包装在try-with-resources
中,将close()
调用委派给Stream
Spliterators
类创建一个Spliterator
来委派许多Stream
的情况?答案 0 :(得分:4)
我认为存储Stream
本身并不令人感到尴尬,而是您拥有sequential coupling。
您必须打电话给hasMoreData
;然后getCurrentStream()
;然后finish()
。如果您仅在有限的几个地方使用该类,则可能在所有这些地方都可以正确使用它。但是您在每个地方使用它都是错误使用它的新机会。
我想说的是,您的经理班实际上只是在让自己变得更难。
for (Optional<Stream<Object>> opt = somethingWhichMightProvideAStream.getNextStream();
opt.isPresent();
opt = somethingWhichMightProvideAStream.getNextStream()) {
try (Stream<Object> stream = opt.get()) { // try-with-resources auto-closes the stream
stream.map(...).filter(...); //etc
}
}
或:
Optional<Stream<Object>> opt;
while ((opt = somethingWhichMightProvideAStream.getNextStream()).isPresent()) {
try (Stream<Object> stream = opt.get()) {
stream.map(...).filter(...); //etc
}
}
这两种情况下的循环声明都不是很漂亮。但这要短一些(大约只要您已经拥有while / try / finally循环就可以了),而且我认为更难使用错误。
(诚然,这里仍然有顺序耦合:您必须记住关闭在可选中返回的流。叹气。)
答案 1 :(得分:1)
将命令性的(while循环,最终尝试)和声明性的(流)代码混合在一起似乎并不正确。 如果所有这些选择都是同步的,我猜它可以在一个管道中完成(根本不需要MyStreamManager)。
我认为您可以考虑将一些逻辑转移到包含对象的方法somethingWhichMightProvideAStream
上,因为将命令式迭代器模式与流API混合看起来并不习惯。例如,它可以返回List
的{{1}}(甚至更好的是Stream
!)而不是Streams
如果确实需要关闭此流,请三思。来自documentation:
流具有
Optional
方法并实现BaseStream.close()
,但是实际上几乎所有流实例在使用后都不需要关闭。通常,只有源是IO通道的流(例如AutoCloseable
返回的流)才需要关闭。