在Java 8中,我想对一个可选对象做一些事情,如果它是存在的,并做另一件事,如果它不存在。
if (opt.isPresent()) {
System.out.println("found");
} else {
System.out.println("Not found");
}
不过,这不是一种“功能性风格”。
Optional有一个ifPresent()方法,但我无法链orElse()方法。
因此,我不能写:
opt.ifPresent( x -> System.out.println("found " + x))
.orElse( System.out.println("NOT FOUND"));
回复@assylias,我不认为Optional.map()适用于以下情况:
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并保存到数据库。
注意,在两个lambda中,我必须返回null。
但是当opt存在时,两个lambdas都将被执行。Obj将被更新,一个新的对象将被保存到数据库中。这是因为在第一个lambda中返回null。orElseGet()将继续执行。
没有一个很好的方法可以打破常规。如果你想在常规的基础上使用更干净的语法,那么你可以创建一个实用工具类来帮助你:
public class OptionalEx {
private boolean isPresent;
private OptionalEx(boolean isPresent) {
this.isPresent = isPresent;
}
public void orElse(Runnable runner) {
if (!isPresent) {
runner.run();
}
}
public static <T> OptionalEx ifPresent(Optional<T> opt, Consumer<? super T> consumer) {
if (opt.isPresent()) {
consumer.accept(opt.get());
return new OptionalEx(true);
}
return new OptionalEx(false);
}
}
然后你可以在其他地方使用静态导入来获得与你想要的语法相近的语法:
import static com.example.OptionalEx.ifPresent;
ifPresent(opt, x -> System.out.println("found " + x))
.orElse(() -> System.out.println("NOT FOUND"));
如果你只能使用Java 8或更低版本:
1)如果你没有弹簧数据,到目前为止最好的方法是:
opt.<Runnable>map(param -> () -> System.out.println(param))
.orElse(() -> System.out.println("no-param-specified"))
.run();
现在我知道对某些人来说,它不是那么可读,甚至很难理解,但对我个人来说,它看起来还不错,我想不出另一种流畅的方法来处理这种情况。
2)如果你足够幸运,你可以使用弹簧数据,最好的方法是
可选# ifPresentOrElse:
Optionals.ifPresentOrElse(opt, System.out::println,
() -> System.out.println("no-param-specified"));
如果你能使用Java 9,你绝对应该使用:
opt.ifPresentOrElse(System.out::println,
() -> System.out.println("no-param-specified"));
对我来说,@Dane White的答案是OK的,首先我不喜欢使用Runnable,但我找不到任何替代品。
这里是我更喜欢的另一个实现:
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:
上面的解决方案为传统的开发方式,当你有价值,想要处理它,但如果我想定义功能和执行将是然后,检查下面的增强;
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();
}
}
Then可用作:
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个东西:
可以很容易地定义一个对象存在之前的功能。
没有为每个可选对象创建对象引用,只有一个,所以内存比GC更少。
它正在实现消费者,以便更好地与其他组件一起使用。
顺便说一下,现在它的名字更有描述性它实际上是Consumer<Optional<?>>