How to calculate a frequency map in Java 8+

A frequency map in Java 8 or above can be created concisely with the help of Stream and Collectors.groupingBy() API.

It provides a general method to count the frequency of elements in a collection:

import java.util.stream.*;
import java.util.*;
import java.util.function.*;
<T> Map<T, Long>  frequencyMap(Stream<T> elements) {
  return elements.collect(
    Collectors.groupingBy(
      Function.identity(),
      HashMap::new, // can be skipped
      Collectors.counting()
    )
  );
}

Any streamable and countable collection can utilise the above method to count the frequency of elements.

Frequency map of list elements

A list can be converted to a stream by calling stream():

import java.util.stream.*;
import java.util.*;
import java.util.function.*;
class HelloWorld {
public static <String> Map<String, Long> frequencyMap(Stream<String> elements) {
return elements.collect(
Collectors.groupingBy(
Function.identity(),
HashMap::new, // can be skipped
Collectors.counting()
)
);
}
public static void main( String args[] ) {
List<String> words = Arrays.asList("hello", "hello", "mighty");
System.out.println(frequencyMap(words.stream()));
}
}

Frequency map of a character array

An array of characters can be converted to a stream using Arrays.stream()

import java.util.stream.*;
import java.util.*;
import java.util.function.*;
class HelloWorld {
public static <Character> Map<Character, Long> frequencyMap(Stream<Character> elements) {
return elements.collect(
Collectors.groupingBy(
Function.identity(),
HashMap::new, // can be skipped
Collectors.counting()
)
);
}
public static void main( String args[] ) {
Character[] letters = {'a', 'b', 'b', 'c', 'c', 'c'};
System.out.println(frequencyMap(Arrays.stream(letters)));
}
}

Frequency map of characters in a string

String characters can be converted to a stream using chars(). However, it returns an integer stream instead of a character stream; so, each integer needs to be converted back to a character using the maptoObj() method:

import java.util.stream.*;
import java.util.*;
import java.util.function.*;
class HelloWorld {
public static <Character> Map<Character, Long> frequencyMap(Stream<Character> elements) {
return elements.collect(
Collectors.groupingBy(
Function.identity(),
HashMap::new, // can be skipped
Collectors.counting()
)
);
}
public static void main( String args[] ) {
String aString = "abc";
System.out.println(frequencyMap(aString.chars().mapToObj(c -> (char) c)));
}
}

Frequency map of an integer array or unboxed type

An array of unboxed typed elements can be converted to a stream using Arrays.stream() and calling boxed():

import java.util.stream.*;
import java.util.*;
import java.util.function.*;
class HelloWorld {
public static <Integer> Map<Integer, Long> frequencyMap(Stream<Integer> elements) {
return elements.collect(
Collectors.groupingBy(
Function.identity(),
HashMap::new, // can be skipped
Collectors.counting()
)
);
}
public static void main( String args[] ) {
int [] numbers = {1, 2, 2, 2, 3, 3};
System.out.println(frequencyMap(Arrays.stream(numbers).boxed()));
}
}

Free Resources

Attributions:
  1. undefined by undefined