不知何故,我应该可以指定一个这样的链,而值通过每个函数传递。
a::create -> a::processing -> a::updating -> a:uploading
在以下文章的上下文中,我想用一个方法链接方法,同时修改它时将结果传递给下一个。
https://dzone.com/articles/higher-order-functions
https://dzone.com/articles/functional-programming-java-8
我的演示将尝试显示我想要的最终结果。它将成为每个方法(如monad)的单个参数/参数,并且应该更容易在链中指定任意数量的方法。
我一直在用其他语言这样做,所以试图了解如何在java中做。
所有方法都会收到相同类型的参数,只有一个。
类值
public class Value {
public String progress = "";
}
类文章
public class Article {
public void create(Value value) {
value.progress += "creating ";
}
public void processing(Value value) {
value.progress += "processing ";
}
public void updating(Value value) {
value.progress += "updating ";
}
public void uploading(Value value) {
value.progress += "uploading ";
}
}
主要类
public class Main {
public static void main(String[] args) {
Value v = new Value();
Article a = new Article();
a.create(v);
a.processing(v);
a.updating(v);
a.uploading(v);
}
}
答案 0 :(得分:4)
鉴于函数式编程中不可变状态是可取的,我已经调整了Value
- 这样可以使进度函数更清晰。
public class Value {
public final String progress;
public Value() {
this("");
}
public Value(final String progress) {
this.progress = progress;
}
}
代替方法,Article
具有功能。可以使用andThen
链接这些函数。
import java.util.function.Function;
public class Article {
private final Function<Value, Value> create = v -> new Value(v.progress + "creating ");
private final Function<Value, Value> processing = v -> new Value(v.progress + "processing ");
private final Function<Value, Value> updating = v -> new Value(v.progress + "updating ");
private final Function<Value, Value> uploading = v -> new Value(v.progress + "uploading ");
public static void main(String[] args) {
final Article a = new Article();
final Value v = a.create.andThen(a.processing).andThen(a.updating).andThen(a.uploading).apply(new Value());
System.out.println(v.progress);
}
}
System.out.println
的结果是creating processing updating uploading
。
<强>更新强>
根据您在方法中创建函数的偏好,您只需要将Article
实现更改为具有此类功能。请注意,我使用Value
的原始(可变)实现。
public class Article {
public Function<Value, Value> create() {
return v -> {
v.progress += "creating ";
return v;
};
}
public Function<Value, Value> processing() {
return v -> {
v.progress += "processing ";
return v;
};
}
public Function<Value, Value> updating() {
return v -> {
v.progress += "updating ";
return v;
};
}
public Function<Value, Value> uploading() {
return v -> {
v.progress += "uploading ";
return v;
};
}
public static void main(String[] args) {
final Article a = new Article();
final Value v = a.create()
.andThen(a.processing())
.andThen(a.updating())
.andThen(a.uploading())
.apply(new Value());
System.out.println(v.progress);
}
}
更新2
已经请求了静态方法引用,所以在这里。我将添加一个附带条件,如果有人向我提供此代码,我想要一个很好的理由进行设计选择。
public class Article {
public static Value create(Value v) {
v.progress += "creating ";
return v;
}
public static Value processing(Value v) {
v.progress += "processing ";
return v;
}
public static Value updating(Value v) {
v.progress += "updating ";
return v;
}
public static Value uploading(Value v) {
v.progress += "uploading ";
return v;
}
public static void main(String[] args) {
Optional<Value> maybeValue = Stream.of(new Value())
.map(Article::create)
.map(Article::processing)
.map(Article::updating)
.map(Article::uploading)
.findFirst();
maybeValue.ifPresent(v -> System.out.println(v.progress));
}
}
答案 1 :(得分:1)
这是使用Java8 Streams进行链接的一种方法。
public static class Article {
public Stream<Value> create(Value value) {
value.progress += "creating ";
return Stream.of(value);
}
public Stream<Value> processing(Value value) {
value.progress += "processing ";
return Stream.of(value);
}
public Stream<Value> updating(Value value) {
value.progress += "updating ";
return Stream.of(value);
}
public Stream<Value> uploading(Value value) {
value.progress += "uploading ";
return Stream.of(value);
}
public Stream<Value> error(Value value) {
return Stream.empty();
}
}
public static void main(String[] args) {
Article a = new Article();
Stream.of(new Value())
.flatMap(a::create)
.flatMap(a::processing)
.flatMap(a::updating)
.flatMap(a::uploading)
.forEach(v -> System.out.println(v.progress));
Stream.of(new Value())
.flatMap(a::create)
.flatMap(a::processing)
.flatMap(a::updating)
.flatMap(a::error)
.forEach(v -> System.out.println(v.progress));
}
creating processing updating uploading
public static class Article {
public Value create(Value value) {
value.progress += "creating ";
return value;
}
public Value processing(Value value) {
value.progress += "processing ";
return value;
}
public Value updating(Value value) {
value.progress += "updating ";
return value;
}
public Value uploading(Value value) {
value.progress += "uploading ";
return value;
}
}
@FunctionalInterface
public interface ThrowingFunction<T, R> {
R apply(T v) throws Exception;
}
public static Function<Value, Stream<Value>> wrap(ThrowingFunction<Value, Value> call) {
return (Value v) -> {
try {
return Stream.of(call.apply(v));
} catch (Exception e) {
return Stream.empty();
}
};
}
public static void main(String[] args) {
Article a = new Article();
Stream.of(new Value())
.flatMap(wrap(a::create))
.flatMap(wrap(a::processing))
.flatMap(wrap(a::updating))
.flatMap(wrap(a::uploading))
.forEach(v -> System.out.println(v.progress));
}
答案 2 :(得分:0)
这不是答案,它不起作用,但我根据给定的答案选择了接近我想要的东西。请根据此发布您的编辑/答案。
值
public class Value {
public String progress = "";
}
文章 - 您可以修改方法的签名以满足需要。
public class Article {
public Value create(Value value) {
value.progress += "creating ";
return value;
}
public Value processing(Value value) {
value.progress += "processing ";
return value;
}
public Value updating(Value value) {
value.progress = "updating ";
return value;
}
public Value uploading(Value value) {
value.progress += "uploading ";
return value;
}
}
Main(我应该可以这样做)
public class Main {
public static void main(String[] args) {
Article a = new Article();
final Value v = a.create
.andThen(a.processing) // or a::processing
.andThen(a.updating) // or a::updating
.andThen(a.uploading)
.apply(new Value());
System.out.println(v.progress);
}
}