当前位置: 首页 > 知识库问答 >
问题:

Java 8按分组并附加到集合

夏侯朝斑
2023-03-14

我有一个返回映射的函数

Map<String, Set<String>> degreeMap = new HashMap<>();
for(Course  course : courses){
    Set<String> cList = degreeMap.get(course.getCourseLevel().toString());
    if(Objects.nonNull(cList)){
        cList.addAll(course.getMasterDegree()); //this is what i want to append to the old set
        degreeMap.put(course.getCourseLevel().toString(), cList);
    } else{
        degreeMap.put(course.getCourseLevel().toString(), new HashSet<>(course.getMasterDegree()));
    }
} 
return degreeMap;

返回courselevel地图-

例如,它读取所有课程并返回如下地图:

{"undergraduate" : ["BTech", "BSc", "BE"],
"masters": ["MTech", "MBA"],
"Executive": ["PGDBM", "EECP"]}

这是我的课程班:

public class Course {
    private List<String> masterDegree;
    private CourseLevel courseLevel;
}

但是我想用Java8风格写这段代码。为此,我尝试了这个:

Map<String, Set<String>> degreeMap = courses.stream().collect(
        Collectors.groupingBy(c -> c.getCourseLevel().toString(),
                Collectors.mapping(c -> c.getMasterDegree(), Collectors.toSet()))
);

这是不工作的,我得到了以下编译时错误:

不存在类型变量的实例,因此List符合字符串推理变量T具有不兼容的边界:等式约束:字符串下限:List

有什么建议,如何实现这一点?


共有3个答案

羊舌兴德
2023-03-14

您可能对Collectors.toMap()方法感兴趣。

这里有一个例子,你可能需要调整,因为我没有测试它。

Map<String, Set<String>> degreeMap = courses.stream()
    .collect(
        Collectors.toMap(
            item -> item.getCourseLevel().toString(), //your key mapping
            item -> item.getMasterDegree(), //your value mapping
            (oldValue, newValue) -> { //your process of aggregation
                if (null == oldValue) {
                    return newValue;
                } else {
                    oldValue.addAll(newValue);
                    return oldValue;
                }
            },
            LinkedHashMap::new //your result initialiser
        )
    );

另外,还有一个提示:您不需要通过密钥获取并检查null,您可以使用。compute()。computeIfAbsent()。地图上的computeiPresent()方法

陆洛城
2023-03-14

我认为你不需要lamda表达式,你应该重构你的代码,让它变得清晰。

        // supposed to be initialied with non-empty values
        // Map<String, Set<String>> degreeMap = ...

        for(Course  course : courses){
            // something like below
            String key = course.getCourseLevel().toString();
            // degreeSet should not be null
            Set<String> degreeSet = course.getMasterDegree();

            // TODO: check nullable
            degreeSet.putAll(degreeMap.get(key));

            degreeMap.put(key, degreeSet);
        } 

        return degreeMap;
张鹏鹍
2023-03-14

未经测试,但看起来,您正在寻找以下内容:

    return courses.stream()
            .collect(Collectors.toMap(course -> course.getCourseLevel().toString(),
                    course -> new HashSet<>(course.getMasterDegree()),
                    (set1, set2) -> Stream.of(set1, set2)
                            .flatMap(Set::stream).collect(Collectors.toSet())));
 类似资料:
  • 问题内容: Java 8中有什么方法可以将一个元素分组而不收集它们?我希望结果再次出现。因为我必须处理大量数据甚至是无限流,所以我无法先收集数据并再次流处理结果。 所有需要分组的元素在第一流中都是连续的。因此,我喜欢使流评估保持懒惰。 问题答案: 无法使用标准Stream API做到这一点。通常,您无法执行此操作,因为将来总是有可能出现属于任何已创建组的新项目,因此,在处理所有输入之前,您无法将组

  • 在Java8中有什么方法可以在中分组元素而不收集它们吗?我希望结果再次成为。因为我必须处理大量的数据,甚至是无限的流,所以我不能首先收集数据,然后再次流化结果。 所有需要分组的元素在第一个流中是连续的。因此,我喜欢保持流评估懒惰。

  • 我尝试使用Java8特性。 我有课 我的最后一个映射类是 因为我是刚到java的,我面临着要完成它的斗争,我尽了最大的努力。是否可以删除空文件和计数?提前致谢

  • 我有一个班级排,比如: a类统计数据: 我有一个行列表 我需要把它转换成一个按id1和id2分组的映射,我需要度量数据以这种形式汇总成Stats对象 我正在使用java stream生成这个,但仍停留在这一点上: 如何将列表转换为另一个对象,该对象包含该列表中所有对象的总和? 还有一种方法可以使用java stream将上述形式的两个输出映射合并为第三个输出映射吗? 例如:- 输入:行列表 结果:

  • 我怎样才能以最有效的方式做到这一点? 用于测试的主类示例

  • 问题内容: 我在PostgreSQL数据库上有两个表,合同和付款。一份合同完成了多次付款。 我有以下两个模型: 我想对每个合同的所有付款进行汇总,并使用以下功能: 但它生成以下查询: 我不要求选择payments.id,因为我必须将其包括在我的汇总或按功能分组中,如错误消息中所述: 可能未处理的SequelizeDatabaseError:错误:列“ payments.id”必须出现在GROUP