java 8 - 流,地图和计数不同

Zem*_*mer 17 java java-8 java-stream

我第一次尝试使用java 8流...

我有一个对象Bid,它代表用户对拍卖中项目的出价.我有一个出价列表,我想制作一张地图,其中包含用户出价的拍卖数量(不同).

这是我的看法:

bids.stream()
         .collect(
             Collectors.groupingBy(
                  bid ->  Bid::getBidderUserId, 
                  mapping(Bid::getAuctionId, Collectors.toSet())
             )
         ).entrySet().stream().collect(Collectors.toMap(
             e-> e.getKey(),e -> e.getValue().size())
        );
Run Code Online (Sandbox Code Playgroud)

它工作,但我觉得我在作弊,因为我流式传输地图的入口集,而不是在初始流上进行操作...必须是一个更正确的方式这样做,但我无法想象出来...

谢谢

Tag*_*eev 23

你可以执行groupingBy两次:

Map<Integer, Map<Integer, Long>> map = bids.stream().collect(
        groupingBy(Bid::getBidderUserId,
                groupingBy(Bid::getAuctionId, counting())));
Run Code Online (Sandbox Code Playgroud)

这样,每个用户在每次竞价中都会有多少出价.因此内部地图的大小是用户参与的拍卖数量.如果您不需要其他信息,可以执行以下操作:

Map<Integer, Integer> map = bids.stream().collect(
        groupingBy(
                Bid::getBidderUserId,
                collectingAndThen(
                        groupingBy(Bid::getAuctionId, counting()),
                        Map::size)));
Run Code Online (Sandbox Code Playgroud)

这正是您所需要的:将用户映射到用户参与的拍卖数量.

更新:还有类似的解决方案,更贴近您的示例:

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

  • 优秀!这正是我所寻找的,"gatherAndThen"方法,我无法弄清楚如何使用.非常感谢 :) (3认同)