Java 8 Streams API HAVING 子句等同于 GroupingBy?

标签 java java-8 stream

我在 Streams API 中遇到了一个难以解决的问题。好吧,据我所知,它是可以解决的,但在一次调用中并不优雅。下面,采用 FeatureContentWeight 对象流,我想按 featurecontent 分组并获得每个最大权重功能和内容。我在最后从 Map 中获取值,因为我不需要维护 Map。问题是,我只想要包含超过 3 个项目的组。因此,我想要超过给定计数的Feature,Content 对 的每个功能和内容的最大权重。在 SQL 中,这只是一个简单的 HAVING 子句。在 Streams API 中,它看起来并不微不足道,但我现在才使用 Streams API 几天。

任何想法表示赞赏。以下是我的方法,

List<FeatureContentWeight> nearestNeighbors = neighborPostings
    .stream()
    .collect(
    groupingBy(
        p -> FeatureContent.Create(p.getFeatureId(), p.getContentId()), 
        collectingAndThen(maxBy(comparingDouble(FeatureContentWeight::getWeight)),Optional::get))).values();

最佳答案

正如您所注意到的,不幸的是,JDK 的 Stream API 中没有流式 GROUP BY 操作(即使有流式 distinct()操作)。 collect() 是一个终端操作,它将组和聚合收集到具体的 Map 中。

但是,如本 article showing SQL clauses and their equivalents in Java 8 Streams 中所述,您可以重新流式传输 Map.entrySet() 并对其执行进一步的操作。

应用于您的代码(我在这里做了一些假设):

Map<FeatureContentWeight, Double> nearestNeighbors = neighborPostings
    .stream()

    // GROUP BY featureId, contentId
    .collect(
        groupingBy(
            p -> FeatureContent.Create(p.getFeatureId(), p.getContentId())
        )
    )

    // HAVING count(*) >= 3
    .entrySet()
    .stream()
    .filter(e -> e.getValue().size() >= 3)

    // SELECT grp, MAX(weight)
    .map(e -> e.getValue().stream().collect(
        maxBy(comparingDouble(w -> w.getWeight))
    ));

关于Java 8 Streams API HAVING 子句等同于 GroupingBy?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26818307/

相关文章:

Java移动跨平台框架

java - 如何将返回 null 的 JTextField 转换为不同的字符串值?

video - 如何使用 FFmpeg 直播本地视频

Java EE 身份验证 : how to capture login event?

java - SimpleDateFormat 中的非法模式字符 'O'

java - 为什么 toList() 不直接在 Java 8 Stream 上

java - 过滤两次 Lambda Java

Java当前时间api中的不同值

java - 有没有一种方法可以使用 Function< 将多个方法减少为一个方法? super T, ?> 作为方法参数?

c++ - 如何为我的类(class)创建 endl 操纵器?