gpt4 book ai didi

java - Java8Optional 与 Stream 中的嵌套 null 检查

转载 作者:行者123 更新时间:2023-12-01 07:44:41 27 4
gpt4 key购买 nike

这是一个关于可能令人困惑的 Streams 行为的问题。我的印象是 .map 操作(因为它在可选中使用)始终是空安全的(我知道这些 .map 是不同的实现,认为它们共享相同的名称)。当我在(列表)流中使用它时得到 NPE 时,我感到非常惊讶。从那时起,我开始将 Objects::nonNull 与流一起使用(均使用 .map 和 .flatMap 操作)。

Q1。 为什么Optional可以在任何级别处理空值,而Streams不能(在任何级别),如下面的测试代码所示?如果这是明智且理想的行为,请给出一个解释(关于它的好处,或者 List Stream 表现得像可选的缺点)。

第二季度。作为后续,是否有一种替代方案可以替代我在下面的 getValues 方法中执行的过多 null 检查(这促使我思考为什么 Streams 的行为不能像Optional 一样)。

在下面的测试中,我只对最里面类的值字段感兴趣。

我在 getValue 方法中使用Optional。

我在 getValues 方法中使用列表中的 Streams。在这种情况下,我无法删除单个非空检查。

import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

public class NestedObjectsStreamTest {
@Getter @AllArgsConstructor
private static class A {
private B b;
}
@Getter @AllArgsConstructor
private static class B {
private C c;
}
@Getter @AllArgsConstructor
private static class C {
private D d;
}
@Getter @AllArgsConstructor
private static class D {
private String value;
}

public static void main(String[] args) {
A a0 = new A(new B(new C(new D("a0"))));
A a1 = new A(new B(new C(new D("a1"))));
A a2 = new A(new B(new C(new D(null))));
A a3 = new A(new B(new C(null)));
A a5 = new A(new B(null));
A a6 = new A(null);
A a7 = null;

System.out.println("getValue(a0) = " + getValue(a0));
System.out.println("getValue(a1) = " + getValue(a1));
System.out.println("getValue(a2) = " + getValue(a2));
System.out.println("getValue(a3) = " + getValue(a3));
System.out.println("getValue(a5) = " + getValue(a5));
System.out.println("getValue(a6) = " + getValue(a6));
System.out.println("getValue(a7) = " + getValue(a7));

List<A> aList = Arrays.asList(a0, a1, a2, a3, a5, a6, a7);

System.out.println("getValues(aList) " + getValues(aList));
}

private static String getValue(final A a) {
return Optional.ofNullable(a)
.map(A::getB)
.map(B::getC)
.map(C::getD)
.map(D::getValue)
.orElse("default");
}

private static List<String> getValues(final List<A> aList) {
return aList.stream()
.filter(Objects::nonNull)
.map(A::getB)
.filter(Objects::nonNull)
.map(B::getC)
.filter(Objects::nonNull)
.map(C::getD)
.filter(Objects::nonNull)
.map(D::getValue)
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
}

输出

getValue(a0) = a0
getValue(a1) = a1
getValue(a2) = default
getValue(a3) = default
getValue(a5) = default
getValue(a6) = default
getValue(a7) = default

getValues(aList) [a0, a1]

最佳答案

Q1. Why is it that Optional can handle nulls at any level, whereas Streams can't (at any level), as shown in my test code below?

流可以“包含”空值。按照约定,Optional 不能(该约定在 javadoc 中进行了解释):要么它为空并且 map 返回空,要么它不为空,然后保证具有非空值。

Q2. As a follow up, is there an alternative to the excessive null-checks that I perform in the getValues method below.

喜欢避免到处使用 null 的设计。

关于java - Java8Optional 与 Stream 中的嵌套 null 检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55564041/

27 4 0