使用Java 8创建int出现的映射

时间:2015-08-07 12:28:27

标签: java java-8

我知道我的问题与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())); 

不编译的原因是什么? 提前谢谢你:)

3 个答案:

答案 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并且不想重复我的错误。

任务是:

  1. 从文件中读取数字
  2. 查找每个号码发生的频率
  3. 找到方法 对于不止一次出现的数字,可以找到很多对。对于 例如,如果数字3出现4次,我们将有6对(我使用Apache的 CombinatoricsUtils.binomialCoefficient for that)。
  4. 我的解决方案:

    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的提交者。