sma*_*ufo 239 java functional-programming optional java-8
在Java 8中,我想对一个Optional对象做一些事情,如果它存在,并做另一件事,如果它不存在.
if (opt.isPresent()) {
System.out.println("found");
} else {
System.out.println("Not found");
}
Run Code Online (Sandbox Code Playgroud)
但这不是一种"功能风格".
Optional有一个ifPresent()方法,但我无法链接一个orElse()方法.
因此,我不能写:
opt.ifPresent( x -> System.out.println("found " + x))
.orElse( System.out.println("NOT FOUND"));
Run Code Online (Sandbox Code Playgroud)
在回复@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;
});
Run Code Online (Sandbox Code Playgroud)
在这种情况下,当opt存在时,我更新其属性并保存到数据库.当它不可用时,我创建一个新的obj并保存到数据库.
请注意我必须返回的两个lambda null.
但是当opt存在时,两个lambdas都将被执行.obj将更新,并将新对象保存到数据库.这是因为return null在第一个lambda中.并且orElseGet()将继续执行.
Zhe*_*lov 180
如果您使用的是Java 9,则可以使用以下ifPresentOrElse()方法:
opt.ifPresentOrElse(
value -> System.out.println("Found: " + value),
() -> System.out.println("Not found")
);
Run Code Online (Sandbox Code Playgroud)
Bas*_*hdy 101
对我来说@Dane White的答案还可以,首先我不喜欢使用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;
}
}
Run Code Online (Sandbox Code Playgroud)
然后 :
Optional<Any> o = Optional.of(...);
OptionalConsumer.of(o).ifPresent(s ->System.out.println("isPresent "+s))
.ifNotPresent(() -> System.out.println("! isPresent"));
Run Code Online (Sandbox Code Playgroud)
更新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();
}
}
Run Code Online (Sandbox Code Playgroud)
然后可以用作:
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);
Run Code Online (Sandbox Code Playgroud)
在这个新代码中,您有三件事:
顺便说一句,现在它的名字更具描述性,实际上是消费者>
Bar*_*cki 74
请参阅Java 8备忘单中的优秀可选项.
它为大多数用例提供了所有答案.
以下简短摘要
opt.ifPresent(x -> print(x));
opt.ifPresent(this::print);
Run Code Online (Sandbox Code Playgroud)
opt.filter(x -> x.contains("ab")).ifPresent(this::print);
Run Code Online (Sandbox Code Playgroud)
opt.map(String::trim).filter(t -> t.length() > 1).ifPresent(this::print);
Run Code Online (Sandbox Code Playgroud)
int len = opt.map(String::length).orElse(-1);
int len = opt.
map(String::length).
orElseGet(() -> slowDefault()); //orElseGet(this::slowDefault)
Run Code Online (Sandbox Code Playgroud)
opt.
filter(s -> !s.isEmpty()).
map(s -> s.charAt(0)).
orElseThrow(IllegalArgumentException::new);
Run Code Online (Sandbox Code Playgroud)
ass*_*ias 50
另一种选择是:
System.out.println(opt.map(o -> "Found")
.orElse("Not found"));
Run Code Online (Sandbox Code Playgroud)
我不认为这会提高可读性.
或者正如Marko建议的那样,使用三元运算符:
System.out.println(opt.isPresent() ? "Found" : "Not found");
Run Code Online (Sandbox Code Playgroud)
小智 37
另一种解决方案是使用如下的高阶函数
opt.<Runnable>map(value -> () -> System.out.println("Found " + value))
.orElse(() -> System.out.println("Not Found"))
.run();
Run Code Online (Sandbox Code Playgroud)
Dan*_*ite 20
没有很好的方法可以开箱即用.如果您希望定期使用更清晰的语法,那么您可以创建一个实用程序类来帮助:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以在其他地方使用静态导入来获得接近你所追求的语法:
import static com.example.OptionalEx.ifPresent;
ifPresent(opt, x -> System.out.println("found " + x))
.orElse(() -> System.out.println("NOT FOUND"));
Run Code Online (Sandbox Code Playgroud)
如果只能使用Java 8或更低版本:
1)如果spring-data到目前为止您没有最好的方法:
opt.<Runnable>map(param -> () -> System.out.println(param))
.orElse(() -> System.out.println("no-param-specified"))
.run();
Run Code Online (Sandbox Code Playgroud)
现在我知道它对某人不是那么可读,甚至很难理解,但对我个人而言看起来不错,而且我认为这种情况下没有另一种流畅的方式。
2)如果您足够幸运,可以使用spring-data最好的方法是
Optionals#ifPresentOrElse:
Optionals.ifPresentOrElse(opt, System.out::println,
() -> System.out.println("no-param-specified"));
Run Code Online (Sandbox Code Playgroud)
如果可以使用Java 9,则绝对应该使用:
opt.ifPresentOrElse(System.out::println,
() -> System.out.println("no-param-specified"));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
279648 次 |
| 最近记录: |