create map of int occurrences using Java 8

If you're open to using a third party library with primitive collections, you can potentially avoid the boxing operations. For example, if you use Eclipse Collections, you can write the following.

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

An IntHashBag is implemented by using an IntIntHashMap, so neither the keys (your integers) nor the values (the counts) are boxed.

The same can be accomplished if you loop through your file and add your results to an IntHashBag from an IntStream.

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

Note: I am a committer for Eclipse Collections.


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

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

Tags:

Java

Java 8