Java 8整型数组转换为映射表

4

我想要将 整型数组 转换为

Map<Integer,Integer> 

使用Java 8流式API
int[] nums={2, 7, 11, 15, 2, 11, 2};
Map<Integer,Integer> map=Arrays
                .stream(nums)
                .collect(Collectors.toMap(e->e,1));

我想要得到一个像下面这样的地图,键将是整数值,值将是每个键的总计数

map={2->3, 7->1, 11->2, 15->1}

编译器报错 "不存在类型变量T,U的实例,因此Integer不能确认为Function的实例"
感谢任何指针来解决这个问题。

3
Arrays.stream(nums).boxed().collect(Collectors.toMap(Function.identity(), i -> 1, Integer::sum)); 的翻译如下:将 nums 数组转换为流(stream),再对每个元素进行装箱(boxed)处理,最后使用 Collectors.toMap(Function.identity(), i -> 1, Integer::sum) 方法将其收集为一个映射表(map)。其中,Function.identity() 表示使用元素本身作为键,i -> 1 表示将值初始化为 1,Integer::sum 表示合并时将值相加。 - Hadi J
3个回答

8
你需要将 IntStream 放入箱中,然后使用 groupingBy 值来获取计数:
Map<Integer, Long> map = Arrays
        .stream(nums)
        .boxed() // this
        .collect(Collectors.groupingBy(e -> e, Collectors.counting()));

或者使用reduce

Map<Integer, Integer> map = Arrays
        .stream(nums)
        .boxed()
        .collect(Collectors.groupingBy(e -> e,
                Collectors.reducing(0, e -> 1, Integer::sum)));

1
谢谢您的回答。如果地图值只是1而不是键计数,那么通过修改Collectors.toMap(e->e,1)是否可以使用呢? - Buddhi
4
@Buddhi,不是这样的,应该是 ...Collectors.toMap(e->e,v->1)... - Hadi J
1
@HadiJ 但在这种特定情况下,您需要使用Collectors.toMap(e-> e,v-> 1,Integer :: sum)来处理重复项。 - Holger
@Holger,是的,我的意思是这个 ...toMap(e->e,1)。感谢您的澄清。 - Hadi J

4

您需要在Stream上调用 .boxed()IntStream 转换为 Stream<Integer>。然后,您可以使用 Collectors.groupingby()Collectors.summingInt() 对值进行计数:

Map<Integer, Integer> map = Arrays.stream(nums).boxed()
        .collect(Collectors.groupingBy(Function.identity(), Collectors.summingInt(i -> 1)));

2
您还可以在不将int值装箱到Map或Map中的情况下完成计数。 如果使用Eclipse Collections,可以将IntStream转换为IntBag,如下所示。
int[] nums = {2, 7, 11, 15, 2, 11, 2};
IntBag bag = IntBags.mutable.withAll(IntStream.of(nums));
System.out.println(bag.toStringOfItemToCount());

输出:

{2=3, 7=1, 11=2, 15=1}

您也可以直接从int数组构造IntBag。
IntBag bag = IntBags.mutable.with(nums);

注意:我是 Eclipse Collections 的提交者。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接