Java 8 的 Optional.ifPresent 和 if-not-Present 的功能风格? [英] Functional style of Java 8's Optional.ifPresent and if-not-Present?
问题描述
在 Java 8 中,如果 Optional
对象存在,我想对它做一些事情,如果它不存在,则做另一件事.
In Java 8, I want to do something to an Optional
object if it is present, and do another thing if it is not present.
if (opt.isPresent()) {
System.out.println("found");
} else {
System.out.println("Not found");
}
不过,这不是一种功能风格".
This is not a 'functional style', though.
Optional
有一个 ifPresent()
方法,但我无法链接一个 orElse()
方法.
Optional
has an ifPresent()
method, but I am unable to chain an orElse()
method.
因此,我不能写:
opt.ifPresent( x -> System.out.println("found " + x))
.orElse( System.out.println("NOT FOUND"));
回复@assylias,我认为Optional.map()
不适用于以下情况:
In reply to @assylias, I don't think Optional.map()
works for the following case:
opt.map( o -> {
System.out.println("while opt is present...");
o.setProperty(xxx);
dao.update(o);
return null;
}).orElseGet( () -> {
System.out.println("create new obj");
dao.save(new obj);
return null;
});
在这种情况下,当 opt
存在时,我更新其属性并保存到数据库.当它不可用时,我创建一个新的 obj
并保存到数据库中.
In this case, when opt
is present, I update its property and save to the database. When it is not available, I create a new obj
and save to the database.
注意在两个 lambda 表达式中我必须返回 null
.
Note in the two lambdas I have to return null
.
但是当 opt
存在时,两个 lambda 表达式都会被执行.obj
将被更新,一个新的对象将被保存到数据库中.这是因为第一个 lambda 中的 return null
.而 orElseGet()
将继续执行.
But when opt
is present, both lambdas will be executed. obj
will be updated, and a new object will be saved to the database . This is because of the return null
in the first lambda. And orElseGet()
will continue to execute.
推荐答案
对我来说@Dane White 的答案是可以的,首先我不喜欢使用 Runnable
但我找不到任何替代方案.
For me the answer of @Dane White is OK, first I did not like using Runnable
but I could not find any alternatives.
这是我更喜欢的另一个实现:
Here another implementation I preferred more:
public class OptionalConsumer<T> {
private Optional<T> optional;
private OptionalConsumer(Optional<T> optional) {
this.optional = optional;
}
public static <T> OptionalConsumer<T> of(Optional<T> optional) {
return new OptionalConsumer<>(optional);
}
public OptionalConsumer<T> ifPresent(Consumer<T> c) {
optional.ifPresent(c);
return this;
}
public OptionalConsumer<T> ifNotPresent(Runnable r) {
if (!optional.isPresent()) {
r.run();
}
return this;
}
}
那么:
Optional<Any> o = Optional.of(...);
OptionalConsumer.of(o).ifPresent(s -> System.out.println("isPresent " + s))
.ifNotPresent(() -> System.out.println("! isPresent"));
更新 1:
当您拥有价值并想要处理它时,传统开发方式的上述解决方案但是如果我想定义功能并且执行将然后,请检查以下增强;
the above solution for the traditional way of development when you have the value and want to process it but what if I want to define the functionality and the execution will be then, check below enhancement;
public class OptionalConsumer<T> implements Consumer<Optional<T>> {
private final Consumer<T> c;
private final Runnable r;
public OptionalConsumer(Consumer<T> c, Runnable r) {
super();
this.c = c;
this.r = r;
}
public static <T> OptionalConsumer<T> of(Consumer<T> c, Runnable r) {
return new OptionalConsumer(c, r);
}
@Override
public void accept(Optional<T> t) {
if (t.isPresent()) {
c.accept(t.get());
}
else {
r.run();
}
}
然后可以用作:
Consumer<Optional<Integer>> c = OptionalConsumer.of(
System.out::println,
() -> System.out.println("Not fit")
);
IntStream.range(0, 100)
.boxed()
.map(i -> Optional.of(i)
.filter(j -> j % 2 == 0))
.forEach(c);
在这个新代码中,你有 3 件事:
In this new code you have 3 things:
- 可以在对象存在之前轻松定义功能.
- 不要为每个 Optional 创建对象引用,只有一个,你的内存比更少的 GC 少得多.
- 它正在实现消费者以更好地与其他组件一起使用.
顺便说一下,现在它的名称更具描述性,它实际上是 Consumer
By the way, now its name is more descriptive it is actually Consumer<Optional<?>>
这篇关于Java 8 的 Optional.ifPresent 和 if-not-Present 的功能风格?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!