Вот коды, которые вы можете попробовать:
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);
}
}
};
}