lingz
lingz

Reputation: 321

Java stream collectors in groovy error on Set::size

I'm trying to do a SELECT MAX(COUNT DISTINCT field_x) FROM stream GROUP BY field_y; in a groovy script using Java Streams / Collectors. Basically, I'd like a solution for COUNT DISTINCT, that I can then feed into .max.

I've been trying the solutions from this post: java 8 - stream, map and count distinct

But getting the error:

unexpected token: : @ line 65, column 114.
   ")}, Collectors.toSet()), Set::size).val

Groovy seems to be having a problem with Set::size and Map::size.

I've imported both java.util.Map and java.util.Set to no avail. Is this a problem with Groovy syntax / importing Java classes or a problem with how I'm using Collectors? For reference, I've merely tried to implement a forEach println on this map from the original post solution:

Map<Integer, Integer> map = bids.stream().collect(
    groupingBy(
            Bid::getBidderUserId,
            collectingAndThen(
                    mapping(Bid::getAuctionId, toSet()),
                    Set::size)));

Apologies if this is more appropriate as a comment, but SO apparently requires more reputation to comment than to ask a question.

Upvotes: 1

Views: 1146

Answers (1)

vsminkov
vsminkov

Reputation: 11250

Unfortunately groovy does not accepts java method reference syntax, however you can use closures and rewrite it like this

Map<Integer, Integer> map = bids.stream().collect(
    groupingBy(
            {bid -> bid.bidderUserId},
            collectingAndThen(
                    mapping({bid -> bid.auctionId}, toSet()),
                    {set -> set.size()})));

Or (a bit shorter) using closure with implicit parameter and method pointer operator

Map<Integer, Integer> map = bids.stream().collect(
    groupingBy(
            {it.&getBidderUserId()},
            collectingAndThen(
                    mapping({it.&getAuctionId()}, toSet()),
                    {it.&size()})));

EDIT

Or even shorter (credits to @cfrick):

Map<Integer, Integer> map = bids.stream().collect(
    groupingBy(
            {it.bidderUserId},
            collectingAndThen(
                    mapping({it.auctionId}, toSet()),
                    {it.size()})));

Upvotes: 5

Related Questions