【问题标题】:create map of int occurrences using Java 8使用 Java 8 创建 int 出现的映射
【发布时间】:2019-11-10 08:39:47
【问题描述】:

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

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

【问题讨论】:

  • Multiset&lt;Integer&gt; occurrences = HashMultiset.create(stream::iterator) 使用番石榴。

标签: java java-8


【解决方案1】:

IntStream 有一个方法collect,其中第二个参数作用于int 而不是对象。使用boxed()IntStream 变成Stream&lt;Integer&gt;

同样counting() 返回一个long

Map<Integer, Long> result = IntStream.range(0, 100).boxed()
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

【讨论】:

  • 谢谢你,彼得。我假设 IntStream 扩展了 Stream,但事实并非如此。
  • 没有boxed()你会得到错误:Expected 3 arguments but found 1
【解决方案2】:

我已经使用彼得的想法解决了手头的任务。 我发布解决方案以防有人正在学习 Java 8 并且不想重复我的错误。

任务是:

  1. 从文件中读取数字
  2. 找出每个数字出现的频率
  3. 找到方法 对于多次出现的数字,可以找到许多对。为了 例如,如果数字 3 出现 4 次,我们将有 6 对(我使用 Apache 的 CombinatoricsUtils.binomialCoefficient )。

我的解决方案:

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()

【讨论】:

    【解决方案3】:

    如果您愿意使用带有原始集合的第三方库,则可以避免装箱操作。例如,如果你使用Eclipse 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 的提交者。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      • 2019-02-14
      • 1970-01-01
      相关资源
      最近更新 更多