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]
下面是您可以尝试的代码:
aList.stream()
.map(applyIfNotNull(A::getB))
.map(applyIfNotNull(B::getC))
.map(applyIfNotNull(C::getD))
.map(applyIfNotNullOrDefault(D::getValue, "default"))
.filter(Objects::nonNull)
.forEach(System.out::println);
使用以下实用方法:
public static <T, U> Function<T, U> applyIfNotNull(Function<T, U> mapper) {
return t -> t != null ? mapper.apply(t) : null;
}
public static <T, U> Function<T, U> applyIfNotNullOrDefault(Function<T, U> mapper, U defaultValue) {
return t -> t != null ? mapper.apply(t) : defaultValue;
}
public static <T, U> Function<T, U> applyIfNotNullOrElseGet(Function<T, U> mapper, Supplier<U> supplier) {
return t -> t != null ? mapper.apply(t) : supplier.get();
}
不知道你觉得怎么样。但我个人不喜欢map(...).map(...)...
。这里我更喜欢的是:
aList.stream()
.map(applyIfNotNull(A::getB, B::getC, C::getD))
.map(applyIfNotNullOrDefault(D::getValue, "default"))
.filter(Objects::nonNull)
.forEach(System.out::println);
public static <T1, T2, T3, R> Function<T1, R> applyIfNotNull(Function<T1, T2> mapper1, Function<T2, T3> mapper2,
Function<T3, R> mapper3) {
return t -> {
if (t == null) {
return null;
} else {
T2 t2 = mapper1.apply(t);
if (t2 == null) {
return null;
} else {
T3 t3 = mapper2.apply(t2);
return t3 == null ? null : mapper3.apply(t3);
}
}
};
}
有人能解释一下如何帮助我们避免? 这段代码不是也容易出现吗?如果是这样的话,那么为什么这个代码比 除了帮助我们了解函数是否实际具有返回值之外,还有什么可能的好处
问题内容: 我有一个对象A的列表。此列表中的每个对象A都包含对象B的列表,而对象B包含对象C的列表。对象C包含一个属性名称,我想使用它使用Java 8进行过滤。 如何使用流在Java 8中编写以下代码以避免嵌套循环: 问题答案: 您可以使用两个,然后使用a,然后可以选择第一个,或者如果没有结果返回:
我有一个对象列表A。此列表中的每个对象A都包含对象B的列表,对象B包含对象C的列表。对象C包含一个属性名称,我想使用java 8进行过滤。 如何使用流在java8中编写下面的代码以避免嵌套循环:
我知道Optionals ifPresent()调用的目的是替换空检查。从Oracle文档中提取代码示例,它在简单情况下似乎非常有用。例如: 我只是想了解为什么这被认为比空检查更好。可读性?表演在我看来,这会对项目性能造成影响,因为必须引入一个新的对象才能容纳我们最终希望获得的对象?总之,为什么这是 如果(声卡!=null),则认为比这更好。
下面是我的代码,按预期工作。但我需要用Optional.ofNullable替换它 如何使用
我尝试在两个列表上循环,过滤嵌套列表,并使用java8特性将结果写回主对象。 因此,到目前为止,位置内部的子列表不会更改,这是显而易见的,因为流和收集确实会创建一个新列表,该列表不会写回位置对象中。所以我的问题是,如果有一种方法可以调用位置对象的setSubList(...)方法并将新列表写入其中。 感谢