Java 8 Group by并追加到一个集合

问题描述 投票:2回答:3

我有函数返回一个Map<String, Set<String>>,代码在java 8之前:

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;
}

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

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

哪个不起作用,我得到以下编译时错误:

没有类型变量的实例存在,以便List符合String推理变量T具有不兼容的边界:等于约束:字符串下限:列表

有什么建议,怎么实现呢?

java collections java-8 group-by collectors
3个回答
3
投票

没有经过测试,但看起来,你正在寻找类似的东西:

    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())));

0
投票

我不认为你需要lambda表达式,你应该重构代码以使其清晰。

        // 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;

0
投票

您可能对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(),. computeIfPresent()方法

© www.soinside.com 2019 - 2024. All rights reserved.