我遇到以下问题。我已实现了管道处理,有时我必须释放资源,例如Files。同时我的管道是异步的,所以它立即释放控制我在Non-lamda实现中有一个关闭方法。我无法使用lambdas插入它。我目前的代码如下:
@FunctionalInterface
public interface Stage<T,Q> {
public Q process(T toProcess);
}
@FunctionalInterface
public interface IntermediatStage<T,Q> extends Stage<T,Q> {
public default <P> IntermediatStage<T,P> nextStage(Stage<Q,P> nextStage) {
return (T t) -> {return nextStage.process(this.process(t)); };
}
}
我需要随后在不同的阶段调用关机方法。问题是用默认方法链接它们我没有它们的可见性。是否有可能以某种方式添加Stages以便能够添加一个关闭钩子,我可以稍后根据管道是异步的事实独立调用?
由于
答案 0 :(得分:3)
您无法仅使用接口和lambda表达式解决所有问题。对于具有如下模式的普通类来说,这看起来很简单:
$('.read').click()
public final class Stage<T,R> {
static final Runnable NO_OP = () -> {};
public static <I,O> Stage<I,O> create(Function<I,O> f) {
return new Stage<>(f, NO_OP);
}
public static <I,O> Stage<I,O> create(Function<I,O> f, Runnable cleanup) {
return new Stage<>(f, cleanup);
}
private final Function<T,R> actualAction;
private final Runnable cleanup;
private Stage(Function<T,R> f, Runnable r) {
actualAction=f;
cleanup=r;
}
public <P> Stage<T,P> nextStage(Function<R,P> nextStage) {
return new Stage<>(actualAction.andThen(nextStage), cleanup);
}
public <P> Stage<T,P> nextStage(Function<R,P> nextStage, Runnable nextCleanup) {
return new Stage<>(actualAction.andThen(nextStage),
cleanup==NO_OP? nextCleanup: () -> { cleanup.run(); nextCleanup.run(); });
}
public R process(T t) {
return actualAction.apply(t);
}
public Function<T, R> getActualAction() {
return actualAction;
}
public void cleanup() {
cleanup.run();
}
public Runnable getCleanup() {
return cleanup;
}
}
类是简单且不变的,但它的实际行为由Stage
和Function
实例确定,如果您愿意,可以通过lambda表达式创建。您可以仅使用普通函数或通过提供函数和清理操作来创建和链接。您将获得两个不同的函数链和清理操作,因此可以独立执行它们。
答案 1 :(得分:2)
如果没有关于如何清理资源的更多信息,可以想象像
这样的东西@FunctionalInterface
public interface Stage<T,Q> {
Q process(T toProcess);
static <T,Q> Stage<T,Q> of(Stage<T,Q> stage){
return stage;
}
default Stage<T,Q> withRelease(Consumer<T> releaser){
return t -> {
Q q = process(t);
releaser.accept(t);
return q;
};
}
}
你可以调用
Stage.of(Thing::process).withRelease(Thing::close)