获取得分为“ x”分的Java8 List <Student>到Map <Marks,List <Name >>的学生列表,且名称数量受限制

时间:2019-08-22 17:38:31

标签: java lambda java-8 java-stream

我想将对象列表转换为Map<K,List<V>>,但是列表中的整体项目是有限的。限制= 1024 此问题有2个阶段:

Student {
    name: String
    marks: Long
}

同一名称可能带有多个标记。在这种情况下,需要添加标记。 第一阶段的预期结果-学生姓名和总成绩

originalStudentList = List<Student>
intermediateMap = Map <String, Long>
newExpectedMap Map<Long, List<String>

阶段1:

originalStudentList.stream()
.collect(Collectors.toConcurrentMap(Student::getName,
                Student::getMarks, (marks1, marks2) -> marks1+marks2));

此输出为-

originalStudentList = [{"a",3},{"b",2},{"c",3},{"d",2},{"a",2},{"f",7},{"e",3}];

intermediateMap = [{"a",5},{"b",2},{"c",3},{"d",2},{"f",7},{"e",3}];

阶段2: 现在,假设我只想要前5名学生的地图

intermediateMap.entrySet()
            .stream
            .collect(Collectors.groupingBy(Map.Entry::getValue,
                Collectors.mapping(Map.Entry::getKey, Collectors.toList())));

使用上面的代码,我将获得下面的地图

newExpectedMap = [{7,{"f"}},{5,{"a"}},{3,{"c","e"}},{2,{"b","d"}}]

但是我想将字符串中的项目数限制为5-所以我想要

newExpectedMap = [{7,{"f"}},{5,{"a"}},{3,{"c","e"}},{2,{"b"}}]

注意:我可以删除b或d,但必须从最后一个条目中删除。如果限制为3,则将从键:3中删除

我停留在第2阶段-但如果可以简化整个流程,我可以修改整个流程。

1 个答案:

答案 0 :(得分:3)

如果我正确理解了您的问题,则无法一步一步实现,而只能使用两个步骤:

Map<Long, List<String>> top5 = students.stream()
        .collect(Collectors.groupingBy(Student::getName, Collectors.summingLong(Student::getMarks)))
        .entrySet().stream()
        .sorted(Map.Entry.<String, Long>comparingByValue().reversed())
        .limit(5)
        .collect(Collectors.groupingBy(Map.Entry::getValue, LinkedHashMap::new,
                Collectors.mapping(Map.Entry::getKey, Collectors.toList())));

第一部分与第一阶段相同,您可以按值对结果进行排序并将结果列表限制为5,这样您可以再次收集结果。如果您想让物品降落在地图中,请像上面一样使用LinkedHashMap

结果将是这样:

{7=[f], 5=[a], 3=[c, e], 2=[b]}