【问题标题】:java 8 - stream, map and count distinctjava 8 - 流,映射和计数不同
【发布时间】:2015-05-17 02:19:21
【问题描述】:

我第一次尝试使用 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())
        );

它有效,但我觉得我在作弊,因为我流式传输地图的条目集,而不是对初始流进行操作......必须是这样做的更正确的方法,但我不能想不通……

谢谢

【问题讨论】:

  • 您能否包含您对投标对象的声明?

标签: java java-8 java-stream


【解决方案1】:

你可以执行两次groupingBy

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

这样您就可以知道每个用户在每次拍卖中的出价数。所以内部地图的大小就是用户参与的拍卖次数。如果您不需要其他信息,可以这样做:

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

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

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

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

【讨论】:

  • 是的,我删除了我的评论,因为我意识到它应该是你刚刚添加的。我在考虑之前就发布了。
  • 太棒了!这正是我想要的,collectingAndThen 方法,我不知道如何使用。非常感谢:)
【解决方案2】:

Tagir Valeev 的答案是正确的 (+1)。这是另外一个使用您自己的 groupBy 下游收集器执行完全相同的操作:

    Map<Integer, Long> map = bids.stream().collect(
               Collectors.groupingBy(Bid::getBidderUserId, 
                                     new Collector<Bid, Set<Integer>, Long>() {

        @Override
        public Supplier<Set<Integer>> supplier() {
            return HashSet::new;
        }

        @Override
        public BiConsumer<Set<Integer>, Bid> accumulator() {
            return (s, b) -> s.add(b.getAuctionId());
        }

        @Override
        public BinaryOperator<Set<Integer>> combiner() {
            return (s1, s2) -> {
                s1.addAll(s2);
                return s1;
            };
        }

        @Override
        public Function<Set<Integer>, Long> finisher() {
            return (s) -> Long.valueOf(s.size());
        }

        @Override
        public Set<java.util.stream.Collector.Characteristics> characteristics() {
            return Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.UNORDERED, Collector.Characteristics.IDENTITY_FINISH));
        }
    }));

【讨论】:

    猜你喜欢
    • 2017-12-04
    • 1970-01-01
    • 1970-01-01
    • 2017-09-22
    • 1970-01-01
    • 2015-02-11
    • 2015-12-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多