Java 8 Streams API HAVING equivalent in GroupingBy?

I ran into a difficult problem in Streams API. Well, this is solvable, but not elegantly within the same call, from what I can say. Below, using the FeatureContentWeight stream of objects, I want to group by Feature and Content and get the maximum weight for each function and content. I get the values ​​from the map at the very end, since I do not need to support the map. The problem is that I only need groups in which there are more than three elements. Therefore, I want the maximum weight for each category and content for Feature and Content pairs to exceed the specified score. In SQL, it will just be just a HAVING clause. This doesn’t look like this in the Streams API, but I have already been in the Streams API for several days.

Any ideas are appreciated.

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

From your description, it seems that you want to filter out the map that is the result of the grouping. Therefore, you can apply the collection toMapto the result of the grouping, and then filter it values()to save only those that are 3 or more in length. You may also be able to skip map creation and use the collection partitioningBy, but this may be more inconvenient.

, , Guava, Maps.filterValues(), , Java 8 ( , ). Guava, Java 8, - :

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

, API JDK Stream GROUP BY ( distinct()). collect() - , Map.

, SQL Java 8, 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))
    ));
+1

resultMap.values ​​(). removeIf (lst -> lst.size () <3)

+1
source

All Articles