如何使用Java8流从MongoDB文档列表中找到每次使用的最低分数

如何使用Java8流从MongoDB文档列表中找到每次使用的最低分数,mongodb,lambda,java-8,java-stream,Mongodb,Lambda,Java 8,Java Stream,假设我在列表中收集了以下MongoDB文档 List<Document> all { "student_id" : 0, "score" : 14.8504 } { "student_id" : 0, "score" : 63.98403 } { "student_id" : 1, "score" : 21.33265 } { "student_id" : 1, "score" : 44.31668 } { "student_id" : 2, "score" : 60.9750 }

假设我在列表中收集了以下MongoDB文档

List<Document> all

{ "student_id" : 0, "score" : 14.8504 }
{ "student_id" : 0, "score" : 63.98403 }
{ "student_id" : 1, "score" : 21.33265 }
{ "student_id" : 1, "score" : 44.31668 }
{ "student_id" : 2, "score" : 60.9750 }
{ "student_id" : 2, "score" : 97.75888 }
{ "student_id" : 3, "score" : 50.81575 }
然而,下面的工作似乎有点太复杂了。有没有更简单的方法

Map<Integer, Double> result = all.stream().
    flatMap(d -> Collections.singletonMap(d.getInteger("student_id"), 
        d.getDouble("score")).entrySet().stream()).
    collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, Math::min));
Map result=all.stream()。
flatMap(d->Collections.singletonMap(d.getInteger(“学生id”),
d、 getDouble(“分数”)).entrySet().stream()。
collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue,Math::min));

提前感谢。

收集器实用程序类中的groupingBy是专门为此任务设计的,因此您应该这样做

Map<Integer, Double> maxScoreByStudentId = this.documents.stream()
            .collect(Collectors.groupingBy(Document::getStudentId, Collectors.collectingAndThen(
                    Collectors.minBy(Comparator.comparingDouble(Document::getScore)), d -> d.get().getScore())));
Map maxScoreByStudentId=this.documents.stream()
.collect(Collectors.groupingBy)(文档::getStudentId,Collectors.collectingAndThen(
Collectors.minBy(Comparator.comparingDouble(Document::getScore)),d->d.get().getScore());
  • groupingBy使用Document::getStudentId作为键构造映射
  • 收集然后做两件事:

    2.1使用minBy(Comparator.comparingDouble(document::getScore))计算每组的最小分数。注意,minBy返回一个可选的

    2.2然后使用lambda d->d.get().getScore()提取分数。由于minBy返回一个可选值,因此有必要使用d.get提取其值


  • 为什么不简单地
    all.stream().collect(toMap(d->d.getInteger(“student_id”),d->d.getDouble(“score”),Math::min);
    flatMap(d->singletonMap(…).entrySet().stream())
    对于获取单个
    映射条目来说真是巴洛克风格
    也会这样做。但是为什么要创建一个
    条目来提取后面的两个值呢?就像,为什么不直接在
    toMap
    收集器中提取这两个值…@assylias和Holger,你说得对。我没想清楚。谢谢。
    Map<Integer, Double> maxScoreByStudentId = this.documents.stream()
                .collect(Collectors.groupingBy(Document::getStudentId, Collectors.collectingAndThen(
                        Collectors.minBy(Comparator.comparingDouble(Document::getScore)), d -> d.get().getScore())));