Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

create map of int occurrences using Java 8

Tags:

java

java-8

I am aware my question is very similar to Count int occurrences with Java8 , but I still cannot solve my case, which must be easier to solve.

The need is to count how many times integers repeat in a stream of integers (will be coming from a file, may be up to 1000000 integers). I thought it might be useful to create a map, where Integer will be a Key, and number of occurrences will be a value.

The exception is

Error:(61, 66) java: method collect in interface java.util.stream.IntStream cannot be applied to given types;
required: java.util.function.Supplier,java.util.function.ObjIntConsumer,java.util.function.BiConsumer found: java.util.stream.Collector> reason: cannot infer type-variable(s) R (actual and formal argument lists differ in length)

However, in Java 8 there is a Collectors.groupingBy, which should suffice

 Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,Collector<? super T, A, D> downstream) 

The problem is that my code is not compiling and I do not see - why. I simplified it to this:

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

What is the reason for not compiling? Thank you in advance :)

like image 982
Nikita Koselev Avatar asked Aug 07 '15 12:08

Nikita Koselev


2 Answers

IntStream has one method collect where the second argument operates on an int not an Object. Using boxed() turns an IntStream into a Stream<Integer>

Also counting() returns a long.

Map<Integer, Long> result = IntStream.range(0, 100).boxed()
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
like image 59
Peter Lawrey Avatar answered Sep 23 '22 05:09

Peter Lawrey


I have solved the task at hand using Peter's idea. I'm posting the solution in case somebody is studying Java 8 and does not want to repeat my mistakes.

The task was to:

  1. read numbers from file
  2. find how often each number occurs
  3. find how many pairs can be found for numbers occurring more than once. For example, if number 3 occurs 4 times, we will have 6 pairs (I used Apache's CombinatoricsUtils.binomialCoefficient for that).

My solution:

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()
like image 39
Nikita Koselev Avatar answered Sep 24 '22 05:09

Nikita Koselev