簡體   English   中英

Java 8 Streams API HAVING子句在GroupingBy中是否等效?

[英]Java 8 Streams API HAVING clause equivalent in a GroupingBy?

我在Streams API遇到了難以解決的問題。 好吧,根據我所知,在一次調用中它是可解決的,但並不優雅。 下面,以FeatureContentWeight對象流FeatureContentWeight ,我想按功能內容進行分組,並獲取每個功能和內容的最大權重 我從數值Map在最后,因為我已經沒有必要維持一個Map 問題是,我只希望其中包含3個以上項目的組 因此,我希望已超過給定計數的功能,內容對的每個功能和內容的最大權重。 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();

從您的描述看來,您似乎要過濾作為分組結果的地圖。 因此,您可以對分組結果應用toMap收集器,然后過濾其values()以便僅保留長度為3或更大的值。 您可能還可以跳過地圖創建並使用partitioningBy收集器,但這可能更尷尬。

最后,對於轉換地圖,我發現Guava的輔助函數(例如Maps.filterValues()提供的語法比Java 8短且可讀性強(流語法對於列表而言是不錯的選擇,但對於地圖而言,有時會變得很糟糕)。 如果您使用的是Java 8,則可以在Guava中使用閉包,因此您可以編寫如下代碼:

Map<A,B> unfiltered = <Java 8 grouping>
return Maps.filterValues(unfiltered, list -> list.size() > 3);

如您所見,不幸的是,JDK的Stream API中沒有流式GROUP BY操作(即使有流式distinct()操作)。 collect()是一個終端操作,它將組和聚合收集到一個具體的Map

但是,如本文所述,其中顯示了Java 8 Streams中的SQL子句及其等效項 ,您可以重新流式傳輸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))
    ));
resultMap.values().removeIf(lst -> lst.size() < 3)

只需從結果中刪除不需要的所有內容

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM