如何使用Java 8流从MongoDB文档列表中查找每个使用的最低分数

时间:2015-08-21 14:40:36

标签: 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 }
{ "student_id" : 2, "score" : 97.75888 }
{ "student_id" : 3, "score" : 50.81575 }

我想使用带有lambda表达式的Java 8流将每个用户的最低分数提取到地图中。期望的结果是

{0=14.8504, 1=21.33265, 2=60.9750, 3=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));

提前致谢。

1 个答案:

答案 0 :(得分:1)

grouping在收集器实用程序类中专门为此任务设计,所以你应该做这样的事情

Map<Integer, Double> maxScoreByStudentId = this.documents.stream()
            .collect(Collectors.groupingBy(Document::getStudentId, Collectors.collectingAndThen(
                    Collectors.minBy(Comparator.comparingDouble(Document::getScore)), d -> d.get().getScore())));
  1. groupingBy使用Document :: getStudentId作为键构建Map。
  2. collectAndThen做了两件事:

    2.1使用minBy(Comparator.comparingDouble(Document :: getScore))计算每个组的最低分数的文档。请注意,minBy返回一个Optional

    2.2然后用lambda d - >提取得分。 d.get()。getScore()。当minBy返回一个Optional时,必须使用d.get

  3. 提取其值