我目前正在Java 8的Future API和Core CompleteableFuture中进行试验。我知道这是一个monad,因此它应该有一个bind-Operator。
现在的想法是我有一棵抽象运算k的树,例如:
O --- > O3 ---> O4 ---> o5
O ---> o2 --/
我想“合并”O3
并O2
进行新的操作O4 = (O3 o O2) (t) = O2(O3(t))
。我的想法是,例如,我O2
要说:将当前节点与合并,O3
并返回一个由串联操作组成的新节点。不幸的是,我已经整夜尝试了,无法解决。同样,由于未知的原因,使用类似运算符的操作O1.mergeWith(O2).mergeWith(O3)
会触发两次调用一次apply方法。
目标是创建一个由其他功能组成的新功能,因此我可以尽可能推迟计算。
public abstract class Operation<T,R> {
// The value a
private final CompletableFuture<R> future;
// Executes the operation on t and returns something (maybe different) of type R
protected abstract R apply(T t);
// Gets the value of the future of this operation
public R get() throws Exception {
return future.get();
}
protected Operation(Supplier<T> s) {
future = CompletableFuture.supplyAsync(s).thenApplyAsync(transform());
}
protected Operation(CompletableFuture<R> f) {
future = f;
}
CompletableFuture<R> createTargetFuture(R _value) {
return CompletableFuture.supplyAsync(() -> _value);
}
<S> Operation<T,S> mergeWith(Operation<R,S> _other) {
CompletableFuture<S> _result = future.thenComposeAsync(
// Method is synchronous, but is run async :) We need the createTargetFuture, otherwise we cannot turn the constant t into a producer.
(t) -> _other.createTargetFuture(_other.apply(t)));
//transform()).thenApplyAsync(_other.transform());
return new Operation<T, S>(_result) {
@Override
protected S apply(T t) {
// What to put here
return null;
}
};
}
protected Function<T,R> transform(){
return this::apply;
}
}
目前尚不清楚您要实现的目标。您的整个Operation
类看起来像是要添加一个CompletableFuture
它自己已经提供的功能。
如果您有一个Supplier<T> s
并且想要推迟其执行,可以CompletableFuture.supplyAsync(s)
按照您已经知道的方法进行。
现在,如果要将aFunction<T,R> f
应用于CompletableFuture<T> a
简单使用的延迟结果CompletableFuture.supplyAsync(()->f.apply(a.join()))
。
对于两个CompletableFuture
s和一个,相同的工作原理BiFunction
:CompletableFuture.supplyAsync(()->f.apply(a.join(),b.join()))
如果您需要将操作包装在某种支持代码中,则可以创建如下的实用程序方法:
public static <T> CompletableFuture<T> create(Supplier<T> s) {
return CompletableFuture.supplyAsync(s);
}
public static <T,R> CompletableFuture<R> create(
Function<T,R> f, CompletableFuture<T> a) {
return CompletableFuture.supplyAsync(()->f.apply(a.join()));
}
public static <T,U,R> CompletableFuture<R> create(
BiFunction<T,U,R> f, CompletableFuture<T> a, CompletableFuture<U> b) {
return CompletableFuture.supplyAsync(()->f.apply(a.join(),b.join()));
}
然后,您可以愉快地执行异步操作,例如:
int i=create((a,b)->a+b, create(()->42),create(()->100)).join();
但是,当然,如果没有任何支持方法,同样的事情也会起作用:
int i=CompletableFuture.supplyAsync(() ->
CompletableFuture.supplyAsync(()->42).join()
+ CompletableFuture.supplyAsync(()->100).join() ).join();
要么
int j=CompletableFuture.supplyAsync(()->42).thenApplyAsync(
a-> a + CompletableFuture.supplyAsync(()->100).join() ).join();
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句