How to perform arithmetic on the result of Collectors.counting()?

122 Views Asked by At

Given:

List<Integer> myIntegers = Arrays.asList(1, 1, 2, 3, 4, 2);

Return:

an Integer = Sum(((Frequency of Integer) / 2)))

I'm able to get the frequency of each integer using Collectors.groupingBy(), but want to then divide each frequency value by 2 and then sum all the values in the map, returning just an Integer:

Map<Integer, Long> myIntegerMap = myIntegers.stream().collect(Collectors.groupingby(Function.identity(), Collectors.counting()));

for(Map.Entry<Integer, Long> a : myIntegerMap.entrySet()){ System.out.print(a.getKey(), + "==>"); System.out.println(a.getValue());}

Output:

1 ==> 2

2 ==> 2

3 ==> 1

4 ==> 1

Desired Output:

( ( 2 / 2 ) + ( 2 / 2 ) + ( 1 / 2 ) + ( 1 / 2 ) ) = 2

5

There are 5 best solutions below

0
WJS On BEST ANSWER

You don't need to use two statements. You can do it in the same construct as doing the frequency count.

First compute the frequencies and then use CollectingAndThen to post process the map and add up the values after dividing by 2 to get the desired result.

long result = myIntegers.stream().collect(Collectors.collectingAndThen(
         Collectors.groupingBy(Function.identity(),
                 Collectors.counting()),
           mp -> mp.values().stream().mapToLong(a->a/2).sum()))

System.out.println(result);

prints

2
0
RancidCrab On

You can do that with a map-reduce approach like so:

  long result = myIntegerMap.values().stream()
            .mapToLong(aLong -> aLong / 2)
            .sum();

Hope I didn't misunderstand your question and this helps.

0
Diego Borba On

If you are using Java8 you can do this way:

int result = myIntegerMap.entrySet().stream()
                .mapToInt(entry -> (int) (entry.getValue() / 2))
                .sum();
2
Stone On
    List<Integer> myIntegers = Arrays.asList(1, 1, 2, 3, 4, 2);
    Map<Integer, Long> myIntegerMap = myIntegers.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
    // get the value field from the map and create another stream to calc the result
    long sum = myIntegerMap.values().stream().map(v -> v/2).mapToLong(i -> i).sum();
0
SrikanthMalladi On
public static Long findSum(List<Integer> list) {
        return list.stream().collect(Collectors.collectingAndThen(
                Collectors.groupingBy(Function.identity(), Collectors.counting()),map -> map.entrySet().stream().map(data -> data.getValue() / 2).mapToLong(Long::longValue).sum()));           
    }