【问题标题】:Grouping by and map value分组依据和映射值
【发布时间】:2018-02-28 12:19:46
【问题描述】:

我正在尝试按(映射)进行分组,然后将值列表转换为不同的列表。

我有地区文件清单:

List<DistrictDocument> docs = new ArrayList<>();

然后我将其流式传输并按城市分组:

Map<String, List<DistrictDocument>> collect = docs.stream()
                .collect(Collectors.groupingBy(DistrictDocument::getCity));

我还有一个方法,它获取 DistrictDocument 并从中创建 Slugable:

private Fizz createFizz(DistrictDocument doc) {
    return new Fizz().name(doc.getName()).fizz(doc.getFizz());
}

有没有办法将该方法放入我上面的流中,以便我得到 Map&lt;String, List&lt;Fizz&gt;&gt; ? 我尝试将第二个参数添加到 groupingBy 但找不到合适的方法并且总是出现编译错误。

编辑: 如果我的 createFizz 返回 List&lt;Fizz&gt; 怎么办?有没有一个选项可以在 Collectors.mapping 中平展这个列表,因为我仍然想要 Map&lt;String, List&lt;Fizz&gt;&gt; 而不是 Map&lt;String, List&lt;List&lt;Fizz&gt;&gt;&gt;

【问题讨论】:

    标签: java java-8 java-stream


    【解决方案1】:

    您需要将Collectors.mapping() 收集器链接到Collectors.groupingBy() 收集器:

    Map<String, List<Fizz>> collect =
        docs.stream()
            .collect(Collectors.groupingBy(DistrictDocument::getCity,
                     Collectors.mapping(d->createFizz(d),Collectors.toList())));
    

    如果createFizz(d) 会返回List&lt;Fizz,您可以使用Java 9 的Collectors.flatMapping 将其展平:

    Map<String, List<Fizz>> collect =
        docs.stream()
            .collect(Collectors.groupingBy(DistrictDocument::getCity,
                     Collectors.flatMapping(d->createFizz(d).stream(),Collectors.toList())));
    

    如果您不能使用 Java 9,也许使用 Collectors.toMap 会有所帮助:

    Map<String, List<Fizz>> collect =
        docs.stream()
            .collect(Collectors.toMap(DistrictDocument::getCity,
                                      d->createFizz(d),
                                      (l1,l2)->{l1.addAll(l2);return l1;}));
    

    【讨论】:

    • d-&gt;createFizz(d) 您可以为此使用方法参考。诚然,我们不知道这门课。
    • @Michael 是的,不知道类是我没有使用方法引用的主要原因。
    • 你能检查我的编辑吗?不幸的是 createFizz 必须返回 List 我似乎无法找到一种方法来整理这个列表。
    • @doublemc 我相信java 9有Collectors.flatMapping,所以你可以写Collectors.flatMapping(d-&gt;createFizz(d).stream(),Collectors.toList())));
    • 如果我最多只能使用 java 8 怎么办?有什么选择吗?
    【解决方案2】:

    如果您想进行双重嵌套分组:

    假设您有一个 EducationData 对象集合,其中包含学校名称、教师姓名和学生姓名。但是你想要一个看起来像这样的嵌套地图:

    你有什么

    class EducationData {
         String school;
         String teacher;
         String student;
    
         // getters setters ...
    }
    

    你想要什么

    Map<String, Map<String, List<String>>> desiredMapOfMpas ...
    
    // which would look like this :
    
    "East High School" : {
         "Ms. Jackson" : ["Derek Shepherd", "Meredith Grey", ...],
         "Mr. Teresa" : ["Eleanor Shellstrop", "Jason Mendoza", ...],
         ....
    }
    

    如何到达

    import static java.util.stream.Collectors.*;
    
    public doubleNestedGroup(List<EducationData> educations) {
         Map<String, Map<String, List<String>>> nestedMap = educations.stream()
            .collect(
                 groupingBy(
                      EducationData::getSchool,
                      groupingBy(
                           EducationData::getTeacher,
                           mapping(
                                EducationData::getStudent,
                                toList()
                           )
                      )
                  )
            );
    }
    

    【讨论】:

      猜你喜欢
      • 2022-01-26
      • 2018-07-28
      • 2015-11-11
      • 1970-01-01
      • 1970-01-01
      • 2020-08-08
      • 1970-01-01
      • 1970-01-01
      • 2018-03-14
      相关资源
      最近更新 更多