【问题标题】:Java: Group By then MapJava: Group By then Map
【发布时间】:2018-08-18 19:14:50
【问题描述】:

我有一个Events 流

public class Event {
    Location location;
    double turnout;
    //... other fields & getters
}

还有一个统计类EventStatistics

public class EventStatistics {
    // Stats properties e.g. turnout standard deviation/median

    public EventStatistics(List<Event> events) {
        // Generate stats
    }
}

我需要按位置对所有事件进行分组并创建位置和事件统计地图Map&lt;Location, EventStatistics&gt;

group by 只是:

Map<Location, List<Event>> byLocation = events.stream().collect(groupingBy(Event::getLocation));

我知道有一个过载的groupingBy(function, collector) 收集器。我可以使用它在单个流中生成我的Map&lt;Location, EventStatistics&gt; 吗?

【问题讨论】:

    标签: java stream java-stream


    【解决方案1】:

    如果您的 EventStatistics 能够接受单个 Events 而不是完整列表,以及合并两个统计信息的方法,如

    EventStatistics {
        public EventStatistics() {}
        public void addEvent(Event e);
        public EventStatistics merge(EventStatistics toMerge);
    }
    

    然后you can do

    groupingBy(Event::getLocation, Collector.of(EventStatistics::new, EventStatistics::accept, EventStatistics::merge));
    

    这里,无参数构造函数是Supplieracceptaccumulatormergecombiner

    【讨论】:

      【解决方案2】:

      您只需要collectingAndThen:

      Map<Location, EventStatistics> result = 
          events.stream()
                .collect(Collectors.groupingBy(Event::getLocation,
                                               Collectors.collectingAndThen(
                                                   Collectors.toList(), 
                                                   EventStatistics::new)));
      

      【讨论】:

        【解决方案3】:

        您可以使用Collector.of(...) 构建自己的Collector,如下所示:

        Map<Location, EventStatistics> collect = events.stream().collect(groupingBy(Event::getLocation,
                Collector.of(ArrayList::new,
                             List::add,
                             (left, right) -> { left.addAll(right); return left; },
                             EventStatistics::new)
        ));
        

        【讨论】:

        • 这段代码不能为我编译。 ArrayList::new 不推断事件类型。我需要指定ArrayList&lt;Event&gt;::new
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-10
        • 1970-01-01
        相关资源
        最近更新 更多