我知道我的问题与Count int occurrences with Java8非常相似 ,但我仍然无法解决我的情况,这必须更容易解决。
需要计算整数流中整数重复的次数(将来自文件,最多可达1000000个整数)。我认为创建一个地图可能很有用,其中Integer将是一个Key,并且出现次数将是一个值。
例外是
错误:(61,66)java:方法在接口中收集 java.util.stream.IntStream不能应用于给定的类型;
需要: java.util.function.Supplier,java.util.function.ObjIntConsumer,java.util.function.BiConsumer 发现:java.util.stream.Collector>原因:不能 推断类型变量R. (实际和正式的参数列表长度不同)
但是,在Java 8中有一个Collectors.groupingBy
,这应该足够了
Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,Collector<? super T, A, D> downstream)
问题是我的代码没有编译,我没有看到 - 为什么。 我将其简化为:
Map<Integer,Integer> result = IntStream.range(0,100).collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
不编译的原因是什么? 提前谢谢你:)
答案 0 :(得分:15)
IntStream有一个方法collect
,其中第二个参数对int
而不是对象进行操作。使用boxed()
将IntStream
转换为Stream<Integer>
同样counting()
会返回long
。
Map<Integer, Long> result = IntStream.range(0, 100).boxed()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
答案 1 :(得分:2)
我用彼得的想法解决了手头的任务。 我正在发布解决方案,以防有人正在研究Java 8并且不想重复我的错误。
任务是:
我的解决方案:
long result = Arrays.stream(Files.lines(Paths.get(fileName)).mapToInt(Integer::parseInt).collect(() ->
new int[BYTE_MAX_VALUE], (array, value) -> array[value] += 1, (a1, a2) ->
Arrays.setAll(a1, i -> a1[i] + a2[i]))).map((int i) -> combinatorics(i, 2)).sum()
答案 2 :(得分:1)
如果您打开使用带有原始集合的第三方库,则可以避免装箱操作。例如,如果您使用Eclipse Collections(以前为GS Collections),则可以编写以下内容。
IntBag integers = Interval.oneTo(100).collectInt(i -> i % 10).toBag();
Assert.assertEquals(10, integers.occurrencesOf(0));
Assert.assertEquals(10, integers.occurrencesOf(1));
Assert.assertEquals(10, integers.occurrencesOf(9));
IntHashBag是使用IntIntHashMap实现的,所以键(你的整数)和值(计数)都没有加框。
如果循环浏览文件并将结果从IntStream添加到IntHashBag,则可以实现相同的效果。
MutableIntBag integers = IntBags.mutable.empty();
IntStream.range(1, 101).map(i -> i % 10).forEach(integers::add);
Assert.assertEquals(10, integers.occurrencesOf(0));
Assert.assertEquals(10, integers.occurrencesOf(1));
Assert.assertEquals(10, integers.occurrencesOf(9));
注意:我是Eclipse Collections的提交者。