无法在IntStream上应用Collectors.groupingBy的问题咨询
问题:int数组流使用Collectors.groupingBy报错的原因及解决方法
这段代码处理String数组时运行正常,但处理int数组时却报错,尽管int会自动装箱为Integer。JShell中的代码及报错内容如下:
jshell> String[] names = new String[]{"apple", "apple", "banana"}; names ==> String[3] { "apple", "apple", "banana" } jshell> Map<String, Integer> stringMap = Arrays.stream(names).collect(Collectors.groupingBy(Function.identity(), Collectors.summingInt(e -> 1))); stringMap ==> {banana=1, apple=2} jshell> int[] nums = new int[]{1,2,3,3,4}; nums ==> int[5] { 1, 2, 3, 3, 4 } jshell> Map<Integer, Integer> numsMap = Arrays.stream(nums).collect(Collectors.groupingBy(Function.identity(), Collectors.summingInt(e -> 1))); | Error: | method collect in interface java.util.stream.IntStream cannot be applied to given types; | required: java.util.function.Supplier<R>,java.util.function.ObjIntConsumer<R>,java.util.function.BiConsumer<R,R> | found: java.util.stream.Collector<java.lang.Object,capture#1 of ?,java.util.Map<java.lang.Object,java.lang.Integer>> | reason: cannot infer type-variable(s) R | (actual and formal argument lists differ in length) | Map<Integer, Integer> numsMap = Arrays.stream(nums).collect(Collectors.groupingBy(Function.identity(), Collectors.summingInt(e -> 1))); | ^-------------------------^
原因分析
Arrays.stream(int[])返回的是IntStream(基本类型专用流),而非Stream<Integer>(装箱后的对象流)。IntStream的collect方法仅支持三参数重载(Supplier、ObjIntConsumer、BiConsumer),不支持直接传入Collector——这是对象流Stream<T>的collect方法才具备的能力。虽然int可以自动装箱为Integer,但IntStream不会自动转换为对象流,必须显式触发装箱操作。
解决方法
调用IntStream.boxed()方法,将基本类型流转换为Stream<Integer>,之后即可正常使用Collectors分组收集器:
jshell> int[] nums = new int[]{1,2,3,3,4}; nums ==> int[5] { 1, 2, 3, 3, 4 } jshell> Map<Integer, Integer> numsMap = Arrays.stream(nums) ...> .boxed() ...> .collect(Collectors.groupingBy(Function.identity(), Collectors.summingInt(e -> 1))); numsMap ==> {1=1, 2=1, 3=2, 4=1}
此外,还可以用Collectors.counting()替代Collectors.summingInt(e -> 1),实现相同统计效果且代码更简洁:
Map<Integer, Long> numsMap = Arrays.stream(nums) .boxed() .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
内容的提问来源于stack exchange,提问作者Manak Bisht
相关产品推荐
相关产品推荐

