从具有设置为值的地图计数项目

时间:2018-05-31 07:58:13

标签: java java-8 java-stream

我有一个项目清单,如下所示

List<SomeModel> smList = new ArrayList<>();

    smList.add(new SomeModel(1L,6.0f));//id = 1L and capacity = 6.0f
    smList.add(new SomeModel(2L,7.0f));
    smList.add(new SomeModel(3L,7.0f));
    smList.add(new SomeModel(4L,7.0f));

现在我将此列表转换为

Map<Float, Set<Long>> complexList = new HashMap<>();
        complexList = smList.stream().collect(Collectors.groupingBy(SomeModel::getCapacity,
                Collectors.mapping(SomeModel::getId, Collectors.toSet())));

这里是complexList 输出为

7.0=[2, 3, 4]
6.0=[1]

现在我需要计算每个“容量”的值的数量,以输出为

7.0=3
6.0=1

我试过

Map<Float, Long> complexCount = complexList.entrySet().stream().
                collect(Collectors.groupingBy(Map.Entry::getKey, 
                        Collectors.mapping(Map.Entry::getValue, Collectors.counting())));
        complexCount.forEach((k,v)->System.out.println(k+"="+v));

并输出

6.0=1
7.0=1

我必须误解理解溪流或不使用正确的方法。任何人都可以提出方法或解决方案吗?流的参考链接也会有所帮助。

4 个答案:

答案 0 :(得分:3)

如果你想要做的就是打印地图的每个键以及相应值的大小,那么就不需要再次流式传输,因为它会导致不必要的开销。简单地迭代complexList,然后像这样打印:

complexList.forEach((k,v)->System.out.println(k+"="+v.size()));

或者如果你真的想要一张地图,那么人们也可以这样做:

Map<Float, Integer> accumulator = new HashMap<>();
complexList.forEach((k,v)->accumulator.put(k, v.size()));

答案 1 :(得分:2)

你使它变得非常复杂。下面更简单的解决方案:

Map<Float, Long> complexCount = complexList
.entrySet()
.stream()
.collect(Collectors.toMap(
               Map.Entry::getKey,
               entry -> new Long(entry.getValue().size())
        )
);

在这里,您只需要致电Collectors.toMap。它有两个函数,一个用于键,另一个用于映射的值。

如果没有使用Long作为Map值类型的限制,那么:

 Map<Float, Integer> complexCount = complexList
    .entrySet()
    .stream()
    .collect(Collectors.toMap(
                   Map.Entry::getKey,
                   entry -> entry.getValue().size()
            )
    );

答案 2 :(得分:1)

试试这个,

Map<Float, Integer> countByKey = sourceMap.entrySet().stream()
        .collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().size()));

答案 3 :(得分:1)

您可以使用多个CollectorcollectingAndThen()。并且甚至不需要将它收集到中间地图中:

import static java.util.stream.Collectors.*;

/* ... */

Map<Float, Integer> collect = smList.stream()
    .collect(groupingBy(SomeModel::getCapacity,
        collectingAndThen(
            mapping(SomeModel::getId, toSet()),
            Set::size
        )
    ));