How to Count the Frequency of Each Element in an Array in Java

Counting how many times each element appears in an array is a fundamental data-processing task with applications such as word frequency analysis, vote counting, inventory tracking, and finding the majority element. This guide covers the standard HashMap approach, a modern Java Streams solution, and a sorting-based alternative.


Problem Statement

Given an array like {4, 2, 4, 7, 2, 4, 8}, the goal is to determine how many times each distinct value appears.

Output:

Advertisement
 
4 -> 3
2 -> 2
7 -> 1
8 -> 1
 

Method 1: Using HashMap (Standard Approach)

 
import java.util.HashMap;
import java.util.Map;

int[] numbers = {4, 2, 4, 7, 2, 4, 8};

Map<Integer, Integer> frequencyMap = new HashMap<>();

for (int num : numbers) {
    frequencyMap.put(num, frequencyMap.getOrDefault(num, 0) + 1);
}

for (Map.Entry<Integer, Integer> entry : frequencyMap.entrySet()) {
    System.out.println(entry.getKey() + " -> " + entry.getValue());
}
 

The key idea is getOrDefault(num, 0). It returns the current count if the element already exists in the map, or 0 if it is being encountered for the first time. Adding 1 updates the frequency in a single statement.


Method 2: Using Java Streams

 
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;

Map<Integer, Long> frequencyMap = Arrays.stream(numbers)
        .boxed()
        .collect(Collectors.groupingBy(
                n -> n,
                Collectors.counting()
        ));
 

Collectors.groupingBy() groups identical elements together, while Collectors.counting() counts how many elements belong to each group. This provides a concise functional alternative to the manual HashMap solution.


Method 3: Sorting-Based Approach (Without HashMap)

 
import java.util.Arrays;

int[] numbers = {4, 2, 4, 7, 2, 4, 8};

Arrays.sort(numbers);

int count = 1;

for (int i = 1; i <= numbers.length; i++) {
    if (i == numbers.length || numbers[i] != numbers[i - 1]) {
        System.out.println(numbers[i - 1] + " -> " + count);
        count = 1;
    } else {
        count++;
    }
}
 

After sorting, duplicate elements become adjacent, allowing consecutive occurrences to be counted in a single pass. This approach avoids hash-based data structures but requires O(n log n) time because of sorting.


Step-by-Step Explanation

HashMap Method

Each element from the array is processed one by one.

Updating the Count

For every element:

  • getOrDefault() retrieves its current frequency.
  • The frequency is incremented by one.
  • The updated value is stored back into the map.

Final Frequency Map

After processing every element, the map contains each unique element as the key and its occurrence count as the value.

Sorting Method

The array is sorted first so that duplicate values become adjacent.

A counter keeps track of consecutive identical values. Whenever a different value is encountered—or the end of the array is reached—the current count is printed and reset.


Internal Working (Memory View)

For the array:

 
{4, 2, 4, 7, 2, 4, 8}
 

The HashMap evolves like this:

 
Process 4
map = {4=1}

Process 2
map = {4=1, 2=1}

Process 4
map = {4=2, 2=1}

Process 7
map = {4=2, 2=1, 7=1}

Process 2
map = {4=2, 2=2, 7=1}

Process 4
map = {4=3, 2=2, 7=1}

Process 8
map = {4=3, 2=2, 7=1, 8=1}
 

Each getOrDefault() and put() operation takes O(1) average time because HashMap uses hashing to locate elements efficiently.


Real-Life Analogy

Imagine counting votes during an election. Every time a vote for a candidate arrives, you look up that candidate's current total and increase it by one. If it's the candidate's first vote, you start their count at zero before incrementing it. This is exactly how getOrDefault() works.


Best Practices

  • Use getOrDefault() instead of manually checking containsKey() because it is cleaner and equally efficient.
  • Use Collectors.groupingBy() with Collectors.counting() when working with Java Streams.
  • Choose the sorting-based approach only when avoiding hash-based data structures is important.
  • Use LinkedHashMap instead of HashMap if you need to preserve insertion order.

Common Mistakes

  1. Using containsKey() before every put() instead of the simpler getOrDefault() approach.
  2. Forgetting to sort the array before applying the sorting-based counting logic.
  3. Making off-by-one mistakes while printing the last frequency after the loop.
  4. Assuming that HashMap preserves insertion order.

Expert Tips

  • Collectors.counting() returns a Long, not an Integer, so be aware of the type difference.
  • Frequency maps are useful for solving related problems such as finding the majority element or the most frequent element.
  • For very large datasets, consider whether you need frequencies for every element or only the top few most frequent values.

Comparison Table

Method Time Complexity Space Complexity Requires Sorting?
HashMap O(n) O(n) No
Streams (groupingBy) O(n) O(n) No
Sorting-Based O(n log n) O(1) Extra (excluding sorting) Yes

Frequently Asked Questions

What is the most efficient way to count the frequency of elements in a Java array?

The HashMap approach using getOrDefault() is the standard solution because it runs in O(n) time.

Can I count frequencies without using a HashMap?

Yes. Sort the array first and then count consecutive identical elements. This uses O(n log n) time and O(1) additional space.

What does getOrDefault() do?

It returns the value associated with a key if it exists. Otherwise, it returns the specified default value, such as 0.

How can I sort the frequencies by their count?

Convert the map entries into a list and sort them using a comparator based on the frequency values.

Does Collectors.groupingBy() preserve insertion order?

No. By default, it returns a HashMap. If insertion order is required, use the overload that accepts a LinkedHashMap::new supplier.

Can this technique be used for counting characters in a String?

Yes. Convert the string into a character array using toCharArray() and apply the same counting logic.

What is the difference between counting frequencies and finding duplicates?

Finding duplicates identifies elements that appear more than once, while frequency counting reports the exact number of occurrences for every element.

How can I find the most frequent element in an array?

After building the frequency map, iterate through its entries and keep track of the element with the highest count.