我如何简洁地写一个|| b其中a和b是可选值?

J. *_*ger 10 functional-programming optional maybe java-8 java-9

我对任何语言的答案感到满意,但我最终想要用Java解答.(Java 8+很好.不仅限于Java 8.我试图修复标签.)

如果我有两个Optional<Integer>值,我如何简洁地计算等价物a || b,意思是:a如果它被定义; 否则b,如果已定义; 否则empty()

Optional<Integer> a = ...;
Optional<Integer> b = ...;
Optional<Integer> aOrB = a || b; // How to write this in Java 8+?
Run Code Online (Sandbox Code Playgroud)

我知道我可以写a.orElse(12),但如果默认的"值"也是Optional怎么办?

显然,在C#中,运营商??做了我想要的.

Nam*_*man 9

您可以遵循以下任何一项:

✓只需使用以下链接链接or: -

Optional<Integer> a, b, c, d; // initialized
Optional<Integer> opOr = a.or(() -> b).or(() -> c).or(() -> d);
Run Code Online (Sandbox Code Playgroud)

实施记录为 -

如果存在Optional值,则返回描述该值的值,否则返回Optional由赋值函数生成的值.


✓或者如@Holger指出的那样,使用streamas: -

Optional<Integer> opOr = Stream.of(a, b, c, d).flatMap(Optional::stream).findFirst();
Run Code Online (Sandbox Code Playgroud)

实施记录为 -

如果存在Stream值,则返回仅包含该值的顺序,否则返回空值Stream.


Chi*_*rlo 8

Optional<Integer> aOrB =  a.isPresent() ? a : b;
Run Code Online (Sandbox Code Playgroud)

  • @DodgyCodeException:`Stream.of(a,b,c,d).flatMap(Optional :: stream).findFirst()` (4认同)
  • 对我来说,当只有两个变量时,这看起来最干净.但是当你有两个以上时它看起来很乱,而Java 9`或`方法允许链接:`a.or(() - > b).或(() - > c).或(() - > d )`. (2认同)

Bye*_*Bye 7

java-8我们没有任何简单链Optional对象的解决方案,但你可以尝试:

Stream.of(a, b)
    .filter(op -> op.isPresent())
    .map(op -> op.get())
    .findFirst();
Run Code Online (Sandbox Code Playgroud)

java9你可以做:

Optional<Integer> result = a.or(() -> b);
Run Code Online (Sandbox Code Playgroud)

  • 流是默认排序的 (2认同)
  • 在Java 9中,您还可以将第一个变体简化为"Stream.of(a,b).flatMap(Optional :: stream).findFirst()",这样可以轻松扩展到更多选项... (2认同)