Java 8 Stream + Map + ForEach + Collect

Swa*_*aju 6 lambda java-8 java-stream

我正在从文件中读取值并获取列表.如下 -

List<String> fields = Utils.readFile("myText.txt", true);
Run Code Online (Sandbox Code Playgroud)

一旦我得到这个,List<String>我想迭代这个列表并将每个值传递给使用该值的函数,查询到DB并准备List<MyCustomObject>并返回相同的值.

在Java 7中实现非常简单,但我无法使用Stream + Map/forEach + Collect操作在Java 8中实现它.

我试过以下 -

Utils.readFile("myText-"+".txt", true)
        .stream()
        .map(str -> getListOfCustomObjForEachStr(str, pstmt))
        .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

但它返回List<List<MyCustomObject>>而不是合并List<MyCustomObject>

getListOfCustomObjForEachStr()方法为上面代码中传递的每个输入str返回一个List.我需要一个合并的List

有人可以指导我在这里可以做什么来获得合并列表?(我是Java 8的新手所以它似乎是一个愚蠢的问题,但任何帮助都表示赞赏)

编辑1 使用FlatMap如下所示实现 - 请建议是否有其他更好的方法来实现它.希望有一天它可以帮助某人:)继续分享.

List<MyCustomObjects> = Utils.readFile("myText-"+".txt", true)
    .stream()
    .map(str -> getListOfCustomObjForEachStr(str, pstmt))
    .flatMap(Collection::stream)
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

Hol*_*ger 8

使用flatMap是获取平面列表的规范方法.您可以使用单步而不是map+ flatMap:

List<MyCustomObjects> list = Utils.readFile("myText-"+".txt", true)
    .stream()
    .flatMap(str -> getListOfCustomObjForEachStr(str, pstmt).stream())
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

您可能会考虑首先getListOfCustomObjForEachStr返回a Stream的替代方法.此外,不存在Files.lines,返回行字符串流而不先填充临时字符串List.

在这种特定情况下,有一种替代方案.考虑到这.collect(Collectors.toList())相当于.collect(ArrayList::new, List::add, List::addAll)¹,你也使用

List<MyCustomObjects> list = Utils.readFile("myText-"+".txt", true)
    .stream()
    .map(str -> getListOfCustomObjForEachStr(str, pstmt))
    .collect(ArrayList::new, List::addAll, List::addAll);
Run Code Online (Sandbox Code Playgroud)

更换addaddAll,这已经足以所有子添加List<MyCustomObjects>s到的结果List<MyCustomObjects>.


¹这就是toList()现在的工作方式,但由于未指定这样做,因此在其他版本中可能会有所不同