Java8多级flatMap最佳实现

Java8多级flatMap最佳实现,java,functional-programming,java-8,java-stream,Java,Functional Programming,Java 8,Java Stream,我有两个代码示例: 代码A: Stream<String> aStream = firstLevelList.stream() .flatMap(firstLevelElement -> firstLevelElement.getSecondLevelList().stream() .flatMap(secondLevelElement -> secon

我有两个代码示例:

代码A:

Stream<String> aStream = firstLevelList.stream()
                            .flatMap(firstLevelElement -> firstLevelElement.getSecondLevelList().stream()
                                .flatMap(secondLevelElement -> secondLevelElement.getThirdLevelList().stream()
                                    .map(thirdLevelElement -> thirdLevelElement.toString())));
Stream aStream=firstLevelList.Stream()
.flatMap(firstLevelElement->firstLevelElement.getSecondLevelList().stream())
.flatMap(secondLevelElement->secondLevelElement.getThirdLevelList().stream())
.map(thirdLevelElement->thirdLevelElement.toString());
代码B:

Stream<String> aStream = firstLevelList.stream()
                            .flatMap(firstLevelElement -> firstLevelElement.getSecondLevelList().stream())
                            .flatMap(secondLevelElement -> secondLevelElement.getThirdLevelList().stream())
                            .map(thirdLevelElement -> thirdLevelElement.toString());
Stream aStream=firstLevelList.Stream()
.flatMap(firstLevelElement->firstLevelElement.getSecondLevelList().stream())
.flatMap(secondLevelElement->secondLevelElement.getThirdLevelList().stream())
.map(thirdLevelElement->thirdLevelElement.toString());

两者都有完全相同的结果,哪一个是最好的实现?为什么?选项1

以下内容读起来很好,感觉更普通:

firstLevelList.stream()
        .flatMap(firstLevelElement -> firstLevelElement.getSecondLevelList().stream())
        .flatMap(secondLevelElement -> secondLevelElement.getThirdLevelList().stream())
        .map(Object::toString);
它避免了@Holger指出的嵌套,这对读者来说很重要

选项2

或者,如果嵌套与代码基样式的其余部分没有冲突,我们可以使用不同的缩进:

firstLevelList.stream().flatMap(
        firstLevelElement -> firstLevelElement.getSecondLevelList().stream().flatMap(
                secondLevelElement -> secondLevelElement.getThirdLevelList().stream().map(Object::toString)
        )
);
选项3

如果仍然感觉太神秘,我们可以提取变量或方法来命名不同的流:

firstLevelList.stream().flatMap(
        firstLevelElement -> firstLevelElement.getSecondLevelList().stream().flatMap(
                secondLevelElement -> getThirdLevelStream(secondLevelElement)
        )
);

Stream<String> getThirdLevelStream(SecondLevelElement secondLevelElement) {
    return secondLevelElement.getThirdLevelList().stream().map(Object::toString);
}
firstLevelList.stream().flatMap(
firstLevelElement->firstLevelElement.getSecondLevelList().stream().flatMap(
secondLevelElement->getThirdLevelStream(secondLevelElement)
)
);
流getThirdLevelStream(SecondLevelElement SecondLevelElement){
返回secondLevelElement.GetHirdlevelList().stream().map(Object::toString);
}
选项4

我们现在可以将这些方法移动到元素类:

firstLevelList.stream().flatMap(FirstLevelElement::getSecondLevelStream);
类FirstLevelElement{
流getSecondLevelStream(){
返回此.getSecondLevelList().stream().flatMap(SecondLevelElement::getThirdLevelStream);
}
集合getSecondLevelList(){…}
}
类二级元素{
流getThirdLevelStream(){
返回这个.getHirdlevelList().stream().map(Object::toString);
}
集合getHirdlevelList(){…}
}
如果流方法在代码中的其他地方被重用,这将增加一些价值

结论


关于这些选项中的哪一个更好,可以有不同的争论。一般来说,它们都很好。

我更喜欢整洁的方法参考:

Stream<String> aStream = firstLevelList.stream()
    .map(FirstLevelElement::getSecondLevelList)
    .flatMap(List::stream)
    .map(SecondLevelElement::getThirdLevelList)
    .flatMap(List::stream)
    .map(Object::toString);
Stream aStream=firstLevelList.Stream()
.map(FirstLevelElement::getSecondLevelList)
.flatMap(列表::流)
.map(SecondLevelElement::GetHirdLevelList)
.flatMap(列表::流)
.map(对象::toString);

如果您能展示您想要归档的内容,可能会有更好的方法,这并不重要。选择你觉得读起来更好的选项。这没有技术上的区别,但是很明显,第二个选项,避免了深嵌套,增加了可读性,因为你不必猜测结尾的括号配对也不想在每行中增加缩进…
Stream<String> aStream = firstLevelList.stream()
    .map(FirstLevelElement::getSecondLevelList)
    .flatMap(List::stream)
    .map(SecondLevelElement::getThirdLevelList)
    .flatMap(List::stream)
    .map(Object::toString);