我有一个List<Records> =
[
{"studentId": "001", "date": "20180705", "courseId": "CS220", "score": "80"},
{"studentId": "001", "date": "20180702", "courseId": "CS320", "score": "75"},
{"studentId": "001", "date": "20180704", "courseId": "CS330", "score": "90"},
{"studentId": "002", "date": "20180703", "courseId": "CS640", "score": "95"},
{"studentId": "002", "date": "20180628", "courseId": "CS530", "score": "80"},
{"studentId": "002", "date": "20180701", "courseId": "CS545", "score": "90"},
{"studentId": "100", "date": "20180708", "courseId": "CS542", "score": "80"},
{"studentId": "100", "date": "20180629", "courseId": "CS240", "score": "97"},
...
]
如何用相同的studentId
对对象进行分组,并只保留列表中得分最高的对象?如下所示:List<Records> =
[
{"studentId": "001", "date": "20180704", "courseId": "CS330", "score": "90"},
{"studentId": "002", "date": "20180703", "courseId": "CS640", "score": "95"},
{"studentId": "100", "date": "20180629", "courseId": "CS240", "score": "97"},
...
]
使用Stream
收集值。您可以在Baeldung上找到一个示例--Java 8按收集器分组指南
2.8.从分组结果中获取最大值或最小值
这可以像一样使用
records.stream()
.collect(
Collectors.groupingBy(
Record::getStudentId,
Collectors.maxBy(Compartor.comparingInt(Record::getPoint))
)
);
返回的映射将每个studentId
作为一个键,并包含具有最大值的实例。使用POJO:的示例
class POJO {
String name;
int value;
//getters
//toString //POJO [%name% %value%]
}
快速测试:
Map<String, Optional<POJO>> map = Stream.of(
new POJO("A", 1), new POJO("A", 2), new POJO("A", 10),
new POJO("B", 8), new POJO("B", 4),
new POJO("C", 4),
new POJO("D", 4), new POJO("D", 1), new POJO("D", 2)
).collect(
Collectors.groupingBy(
POJO::getName,
Collectors.maxBy(
Comparator.comparingInt(POJO::getValue)
)
)
);
System.out.println(map);
{A=可选[POJO[A10]],
B=可选[POJO[B8]],
C=可选[POHO[C4],
D=可选[POLO[D4]}
这可以通过java8的流来完成。
records.stream()
.collect(Collectors.toMap(Records::getStudentId ,Records::getScore,(s1,s2)->Math.max(s1,s2)))
toMap方法的第三个参数(合并函数(总是选择较大的分值。