SwadhyAI Notes

All Java notes

How to Count Character Frequency in Java

The Challenge

Count how many times each character appears in a string!

Solutions

Method 1: Using HashMap

java
import java.util.HashMap;

String text = "hello";
HashMap<Character, Integer> freq = new HashMap<>();

for (char c : text.toCharArray()) {
    freq.put(c, freq.getOrDefault(c, 0) + 1);
}

for (char c : freq.keySet()) {
    System.out.println(c + ": " + freq.get(c));
}
// Output:
// h: 1
// e: 1
// l: 2
// o: 1

Method 2: Using Array (for lowercase letters)

java
String text = "hello";
int[] freq = new int[26];

for (char c : text.toCharArray()) {
    freq[c - 'a']++;
}

for (int i = 0; i < 26; i++) {
    if (freq[i] > 0) {
        System.out.println((char)(i + 'a') + ": " + freq[i]);
    }
}

Method 3: Using Java 8 Streams

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

String text = "hello";
Map<Character, Long> freq = text.chars()
    .mapToObj(c -> (char) c)
    .collect(Collectors.groupingBy(c -> c, Collectors.counting()));

freq.forEach((k, v) -> System.out.println(k + ": " + v));

Did You Know?

Character frequency analysis is used in cryptography to break simple substitution ciphers! The letter 'e' is the most common in English.

Pro Tip

Use TreeMap instead of HashMap to get characters in sorted order automatically!

Real-World Use Cases

  • Cryptography: Frequency analysis for code breaking
  • Text analysis: Identify patterns in text
  • Data compression: Huffman coding algorithms
  • Spell checking: Analyze character distributions
›Short versionOpen if you only have a minute.
  • A Map from character to count records each char once per occurrence.
  • getOrDefault(c, 0) + 1 is the update. Merge does the same job.
  • HashMap does not promise iteration order. Two runs can print different orders.
  • An int[26] drops uppercase letters, digits, and spaces, or throws if you index them anyway.

Character frequency

Count how often each character appears in text.

Working approach

  • Use Map<Character, Integer> for general text.
  • Use LinkedHashMap when the first-seen order must be stable, or TreeMap when the keys should be sorted.
  • Skip spaces only if the contract says they are not characters you are counting.

Walk the sample

  1. Input "hello"
  2. h, e, and o land at 1
  3. l moves from 1 to 2
  4. The map holds those four keys

The trap

Tests that depend on HashMap.toString() order fail when the table resizes or the JDK changes. The counts can be right and the test still fails.

java
static Map<Character, Integer> frequencies(String text) {
    Map<Character, Integer> counts = new LinkedHashMap<>();
    for (int i = 0; i < text.length(); i++) {
        char c = text.charAt(i);
        counts.merge(c, 1, Integer::sum);
    }
    return counts;
}

Why can the same HashMap print its keys in a different order on the next run?

HashMap orders entries by hash buckets, not by insertion. Nothing in the contract says "hello" prints as h, e, l, o.

Use LinkedHashMap for first-seen order. A 26-slot array is a different shortcut, and it is wrong as soon as the text is not lowercase a-z.

Time O(n), space proportional to the number of distinct chars.

Easy to get wrong

  • Asserting on HashMap iteration order.
  • Using a 26-slot array for mixed text.