如何在使用JAVA 8 Streams对子进行分组时获取父对象计数

时间:2017-07-31 05:40:52

标签: java java-8 java-stream

我有以下结构

class A
{
    List<B> b;
}

class B
{
    List<C> c;
}

class C
{
    int port;
}

我希望按端口分组并获取对象B ex的计数: [443:2](B的2个对象具有端口443的C对象)

3 个答案:

答案 0 :(得分:0)

以下流返回所需的值:

Map<Integer, Long> countMap = a.getB().stream()
            .flatMap(b -> b.getC().stream().distinct())
            .map(C::getPort)
            .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

a.getB().stream())开始B s的流 flatMap(b->b.getC())展示B s流,其中每个元素包含List<C>Stream C个,并删除重复项以避免计算单个B两次,当它有多个C s具有相同的端口时。确保C s等于仅比较端口 然后我map每个C到一个端口和
collect,按int port分组(现在为identity),这将成为返回Map中的关键字及其发生次数。

答案 1 :(得分:-1)

Map<Integer, Long> map = a.getB().stream()
    .flatMap(x -> x.getC().stream())
    .map(C::getPort)
    .collect(Collectors.groupingBy(x -> x, Collectors.counting()));

将所有C合并为一个流并映射到port,然后按port分组

更新

a.getB().stream()
    .map(x -> x.getC().stream()
        .map(C::getPort)
        .distinct()
        .collect(Collectors.toList()))
    .flatMap(Collection::stream)
    .collect(Collectors.groupingBy(x -> x, Collectors.counting()));``

答案 2 :(得分:-1)

这取决于B是否可以有重复的C元素。

如果B不能有重复的C元素:

IntStream Integer> ports = a.b.stream().flatMap(bElem -> bElem.c.stream()).map(cElem -> Integer.valueOf(cElem.port));

Map<Integer, Long> countByPort = ports.collect(Collectors.groupingBy(Function.identity(), Collectors.counting());

如果B可以有重复的C元素:

基于端口实现C equals / hashcode方法。然后在&#34;端口&#34;中做一个小改动。流分配:

IntStream Integer> ports = a.b.stream().flatMap(bElem -> bElem.c.stream().distinct()).map(cElem -> Integer.valueOf(cElem.port));

注意&#34; distinct&#34;。

编辑:我收到的是因为任何负面原因。因此,将尝试解释为什么这实际上计算每个特定端口的B数,这是用户要求的。首先,我们列出所有B上的所有端口。 B上的每个存在都是列表中的条目(因此相同的端口将显示为包含在其中的B的次数)。然后我只计算该列表上每个端口的次数。 这是Bs esch端口的数量包含在