使用Java 8 Stream
API,我想按照以下方式注册“完成钩子”:
Stream<String> stream = Stream.of("a", "b", "c");
// additional filters / mappings that I don't control
stream.onComplete((Completion c) -> {
// This is what I'd like to do:
closeResources();
// This might also be useful:
Optional<Throwable> exception = c.exception();
exception.ifPresent(e -> throw new ExceptionWrapper(e));
});
之所以要这样做,是因为我想将资源包装在Stream
供API客户端使用的资源中,并且我希望Stream
资源一旦被使用就自动清除。如果可能的话,客户可以致电:
Collected collectedInOneGo =
Utility.something()
.niceLookingSQLDSL()
.moreDSLFeatures()
.stream()
.filter(a -> true)
.map(c -> c)
.collect(collector);
而不是当前需要什么:
try (Stream<X> meh = Utility.something()
.niceLookingSQLDSL()
.moreDSLFeatures()
.stream()) {
Collected collectedWithUglySyntacticDissonance =
meh.filter(a -> true)
.map(c -> c)
.collect(collector);
}
理想情况下,我想了解java.util.stream.ReferencePipeline
的各种方法,例如:
@Override
final void forEachWithCancel(Spliterator<P_OUT> spliterator, Sink<P_OUT> sink) {
try {
// Existing loop
do { } while (!sink.cancellationRequested() && spliterator.tryAdvance(sink));
}
// These would be nice:
catch (Throwable t) {
completion.onFailure(t);
}
finally {
completion.onSuccess();
}
}
使用现有的JDK 8 API有没有简便的方法?
除了flatMap
基于解决方案(由@Holger提出)以外,任何拦截终端操作的解决方案都将易碎于以下代码:
Stream<String> stream = getAutoCloseableStream();
if(stream.iterator().hasNext()) {
// do something if stream is non-empty
}
根据规范,此类使用绝对合法。不要忘了,iterator()
并spliterator()
为终端流操作,但其执行后,你仍然需要流源的访问。同样,在任何状态下放弃Iterator
或Spliterator
都是完全有效的,因此您只是不知道是否会进一步使用它。
您可以考虑劝告用户不要使用iterator()
和spliterator()
,但是这段代码呢?
Stream<String> stream = getAutoCloseableStream();
Stream.concat(stream, Stream.of("xyz")).findFirst();
这在内部spliterator().tryAdvance()
用于第一个流,然后将其放弃(如果close()
显式调用生成的流,则将关闭)。您将需要询问用户也不要使用Stream.concat
它。据我在您的图书馆内部所知,您经常使用iterator()
/
spliterator()
,因此您将需要重新访问所有这些地方以解决可能的问题。而且,当然还有许多其他库也使用iterator()
/,spliterator()
并且此后可能会短路:所有这些库都将与您的功能不兼容。
为什么flatMap
基于解决方案的方法在这里起作用?因为在第一次调用hasNext()
or时,tryAdvance()
它会将 整个
流内容转储到中间缓冲区中并关闭原始流源。因此,根据流大小,您可能会浪费很多中间内存,甚至会浪费大量内存OutOfMemoryError
。
您也可以考虑将PhantomReference
s
保留在Stream
对象上并监视ReferenceQueue
。在这种情况下,完成将由垃圾收集器触发(这也有一些缺点)。
总之,我的建议是继续尝试资源。
处理完提交无效数据的情况,本节我们要完成注册表单的功能,如果提交的数据有效,就把用户存入数据库。我们先尝试保存用户,如果保存成功,用户的数据会自动存入数据库,然后在浏览器中重定向,转向新注册用户的资料页面,页面中还会显示一个欢迎消息,构思图如图 7.19 所示。如果保存用户失败了,就交由上一节实现的功能处理。 图 7.19:注册成功后显示的页面构思图 7.4.1 完整的注册表单 要完成注册表单的功
我目前正在写一个wordpress插件,我遇到了一些问题。我的功能在插件激活时不运行。。。谁能告诉我问题出在哪里? 但不幸的是,安装功能不起作用......但当外部类中的代码安装功能是工作
我们正在尝试让一个iOS的应用程序被批准进入AppStore。我们正在我们的应用程序中利用Spotify API的一部分,因此正在使用Spotify网络授权流。 在Spotify提供的登录页面上,它显示了“注册”链接和登录链接。苹果不喜欢这样,因为它违反了“准则3.1.1 -应用内商业支付购买”,因为我们在我们的应用内推广其他应用。我们发现添加< code>nosignup和< code>noli
我正在使用kafka和elasticsearch设置flink流处理器。我想重播我的数据,但当我将并行度设置为1以上时,它不会完成程序,我认为这是因为Kafka流只看到一条消息,将其标识为流的结尾。 有没有办法告诉flink消费群中的所有线程在一个线程完成后立即结束?
DaoCloud 账号的注册 感谢您对 DaoCloud 的关注和支持,本文将带您一步一步地加入到 DaoCloud 的大家庭中。希望您能通过 DaoCloud 快速地学习并灵活地使用 Docker 进行项目代码的开发、测试和部署。 在使用 DaoCloud 提供的优质服务之前,您需要先注册一个属于您或您的团队的 DaoCloud 账号。DaoCloud 十分重视用户体验的简易性和灵活性,所以我们
我正在了解Confluent的模式注册表,以满足所有模式管理需求。 我不太理解他们的版本控制方法...有一个的概念,我将其视为一个名称空间。据我所知,subject在模式注册表中必须是唯一。 然后是模式id,或者只是,它也是唯一的。 最后,还有一个。 以下是文档中的片段: :此主题的架构版本,每个主题从1开始 :全局唯一的架构版本id,在所有主题中的所有架构中都是唯一的 因此,一旦我想修改特定主题