Lambda函数带有Optional而不是嵌套if else


Optional<String> myData;
Set<String> mySet;
if(myData.isPresent()) {
if(myData.get().contains(“testValue”)) {
mySet.add(“somedata”);
}
}
if(!myData.isPresent()) {
mySet.add(“someotherdata”);
}

我有一个这样的场景。我有嵌套的if-else块,我需要使用lambda函数将其转换为Java8映射。我该怎么做呢?

这将重现您之前的结果,但略有改变。我认为流解决方案既不必要也不可取。

  • 如果数据存在但不存在testValue,则导致empty set
  • 如果数据不存在,
  • 将导致包含someotherdata的集合
  • 结果在包含somedata的集合中,如果数据存在并且匹配testValue
String result = myData.isPresent() ?
(myData.get().contains("testValue") ? "somedata" : "") :
"someotherdata";
if (!result.isBlank()) {
mySet.add(result);
}

您可以重新使用您的Optional(这只适用于您的代码,如最初呈现的[以防您编辑它]):

Optional<String> myData = ...;
myData.ifPresent(value -> {
if (value.contains("testValue")) {
mySet.add("somedata"),
}
});
if (!myData.isPresent()) {
mySet.add("someotherdata");
}

如果你使用的是Java 11,你应该使用:

myData.ifPresentOrElse(
value -> {
if (value.contains("testValue")) {
mySet.add("somedata");
}
}, 
() -> mySet.add("someotherdata")
);

这是由你来决定哪一个更好(第一个避免在两个部分做两次mySet.add)。

[edit]修复了每个评论的答案和编译问题。

您可以使用filter来避免本例中的嵌套逻辑。第二个案例没有嵌套逻辑,看起来很好。

myData.filter(d -> d.contains("testValue"))
.ifPresent(mySet::add);
if(!myData.isPresent()) {
mySet.add(“someotherdata”);
}

好吧,如果你坚持:

Optional<String> myData = Optional.of("x");
Set<String> mySet = myData
.<Set<String>>map(s -> s.contains("testValue") ? Set.of("somedata") : Set.of())
.orElse(Set.of("someotherdata"));
System.out.println(mySet);

本例中的输出:

[]

测试其他可选项:

Optional<String> myData = Optional.of("x testValue x");
[somedata]

Optional<String> myData = Optional.empty();
[someotherdata]

我自己的偏好是使用NoDataFound回答的后半部分所示的ifPresentOrElse()

最新更新