简体   繁体   English

Java 8 Stream + Map + ForEach + Collect

[英]Java 8 Stream + Map + ForEach + Collect

I am reading values from a File and get List.我正在从文件中读取值并获取列表。 like below -像下面 -

List<String> fields = Utils.readFile("myText.txt", true);

Once I get this List<String> I want to iterate through this list and pass each value to a function which uses this value, queries into DB and prepares a List<MyCustomObject> and returns the same.一旦我得到这个List<String>我想遍历这个列表并将每个值传递给一个使用这个值的函数,查询到数据库并准备一个List<MyCustomObject>并返回相同的值。

Implementing in Java 7 is quite easy but I'm unable to get it in Java 8 using Stream + Map/forEach + Collect operations.在 Java 7 中实现非常简单,但我无法使用 Stream + Map/forEach + Collect 操作在 Java 8 中实现它。

I have tried the below -我已经尝试了以下 -

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

But it returns a List<List<MyCustomObject>> instead of merged List<MyCustomObject>但它返回一个List<List<MyCustomObject>>而不是合并的List<MyCustomObject>

getListOfCustomObjForEachStr() method returns a List for each input str passed in the above code. getListOfCustomObjForEachStr() 方法为上述代码中传递的每个输入 str 返回一个列表。 And I need a merged List我需要一个合并的列表

Can someone please guide me what can be done here to get a merged list?有人可以指导我在这里可以做什么来获得合并列表吗? (I'm new to Java 8 so it might seem a silly question but any help is appreciated) (我是 Java 8 的新手,所以这似乎是一个愚蠢的问题,但感谢任何帮助)

Edit 1 Got this implemented like below using FlatMap - Kindly suggest if any other better way to do it.编辑 1使用 FlatMap 实现如下所示 - 请建议是否有其他更好的方法来做到这一点。 Hope it helps someone somewhere someday :) Keep sharing.希望有一天能在某个地方帮助某人:) 继续分享。

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

Using flatMap is the canonical way to get a flat list.使用flatMap是获取平面列表的规范方法。 You may use a single step instead of map + flatMap :您可以使用单个步骤而不是map + flatMap

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

You may think about an alternative to getListOfCustomObjForEachStr returning a Stream in the first place.首先,您可能会考虑getListOfCustomObjForEachStr的替代getListOfCustomObjForEachStr返回Stream Further, not the existence of Files.lines , which returns a stream of line strings without filling a temporary List first.此外,不存在Files.lines ,它返回行字符串流而不先填充临时List

In this specific case, there is an alternative.在这种特定情况下,还有另一种选择。 Considering that .collect(Collectors.toList()) is equivalent to .collect(ArrayList::new, List::add, List::addAll) ¹, you also use考虑到.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);

replacing add with addAll , which is already sufficient to add all sub- List<MyCustomObjects> s to the result List<MyCustomObjects> .addAll替换add ,这已经足以将所有子List<MyCustomObjects>添加到结果List<MyCustomObjects>


¹ That's how toList() works now, but since it not specified to do this, it might be different in other versions ¹ 这就是toList()现在的工作方式,但由于未指定这样做,因此在其他版本中可能会有所不同

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM