声明函数映射值并在它们存在时使用它们是很方便的。
在你有几个强制对象和几个Optionals的情况下,我发现自己将其他的包装在Optional.of(mandatoryObject)中,所以我可以在它们上面使用相同的表达式而不用向后写它们。
Food vegetables = Food.someVegetables();
Optional<Food> condiment = Food.someCondiment();
Optional<Food> spices = Food.someSpices();
condiment.map(prepare).ifPresent(putOnPlate);
spices.map(prepare).ifPresent(putOnPlate);
但是我不喜欢这段代码:
putOnPlate.accept(prepare.apply(vegetables));
所以我把它包起来:
Optional.of(vegetables).map(prepare).ifPresent(putOnPlate);
但这是错的,因为蔬菜(在这个例子中)实际上不是可选的。它们非常重要,我给大家的印象是它们是可选的。
所以我的问题是:java中有一些类如java.util.Mandatory所以我可以写:
Mandatory.of(vegetables).map(prepare).definitelyPresentSo(putOnPlate);
答案 0 :(得分:28)
是的,有这样的API。您可以替换
Optional.of(vegetables).map(prepare).ifPresent(putOnPlate);
与
Stream.of(vegetables).map(prepare).forEach(putOnPlate);
现在不得不忍受单元素Stream
是任意元素流(包括可能的空流)的特殊情况这一事实。
但您可以一次处理所有必需元素
Stream.of(mandatory1, mandatory2, mandatory3 /* etc */).map(prepare).forEach(putOnPlate);
甚至可以合并可选元素,但它不会像应该的那样方便,因为Optional.stream()
将在Java 9之前引入。
答案 1 :(得分:10)
Optional
背后的主要思想是抽象可空性(摆脱空检查)并提供一个流畅的API来处理可选值。
如果值始终存在,则无需抽象(至少没有任何实际值),因此纯Java中不存在此类工具。
在其他函数式语言中,您有多个monadic&#39;像Optional
这样的工具可用于不同的用例。如果你想把它们带到Java,Javaslang可能是最好看的地方。您可以找到Option
,Try
,Lazy
,Validation
,Either
,Future
,Tuple
等工具Collections API
允许以您描述的类似方式进行编码。
答案 2 :(得分:4)
我可能错了,但如果您不想使用Optional
,则可以只使用一个对象的Stream
。而不是
Optional.of(vegetables).map(prepare).ifPresent(putOnPlate);
你可以使用:
Stream.of(vegetables).map(prepare).forEach(putOnPlate);
结果将是相同的。如果蔬菜为空,则两种方法都会抛出NPE
。
Arrays.asList(10, null).forEach(value -> {
Optional.of(value).map(x -> x.toString()).ifPresent(System.out::println);
Stream.of(value).map(x -> x.toString()).forEach(System.out::println);
});
NPE安全版本将是
Optional.ofNullable(value).map(x -> x.toString()).ifPresent(System.out::println);
Stream.of(value).filter(Objects::nonNull).map(x -> x.toString()).forEach(System.out::println);
Optional
只是一个对象的容器,可能包含也可能不包含非null值。
答案 3 :(得分:0)
您似乎在寻找@NonNull Food
类型。