Java ProgramsStringsFind Character Frequency

Find Character Frequency in Java

intermediate·  Strings  ·  String

Problem

Character frequency means counting how many times each individual character appears in a string.

Given a string, count how many times each character appears.

Input
success
Output
s: 3, u: 1, c: 2, e: 1

Java Program

Java
import java.util.LinkedHashMap; import java.util.Map; public class CharacterFrequency { public static void main(String[] args) { String str = "success"; Map<Character, Integer> freq = new LinkedHashMap<>(); for (char c : str.toCharArray()) { // getOrDefault(c, 0) reads the current count, or 0 if unseen, then increments it freq.put(c, freq.getOrDefault(c, 0) + 1); } for (Map.Entry<Character, Integer> entry : freq.entrySet()) { System.out.println(entry.getKey() + ": " + entry.getValue()); } } }

Output

s: 3 u: 1 c: 2 e: 1

Core Logic

A map tracking each character's running count, updated in one pass, is all it takes — the same idea as counting word frequency, just one level smaller.

How It Works
  1. 1A LinkedHashMap<Character, Integer> named freq tracks each character's count, preserving the order characters were first seen.
  2. 2freq.getOrDefault(c, 0) reads the current count for a character, or 0 if it hasn't been seen yet.
  3. 3Adding 1 and calling freq.put(c, ...) stores the updated count in one line.
  4. 4entrySet() is iterated afterward to print every character alongside its final count.
In "success", 's' ends with a count of 3, 'c' ends with a count of 2, and 'u' and 'e' each end with a count of 1.
💡

Key Point: A plain HashMap would give the same counts but in an unpredictable order — LinkedHashMap is what keeps the output in first-appearance order.

Complexity
Time Complexity: O(n)Space Complexity: O(n)

Why: Each character is visited once to update its count, and the map holds one entry per distinct character, up to n in the worst case.

Key Concepts

LinkedHashMapgetOrDefault()entrySet()

Approach 2: Java 8

Java
import java.util.LinkedHashMap; import java.util.Map; import java.util.stream.Collectors; public class CharacterFrequencyStream { public static void main(String[] args) { String str = "success"; // Groups equal characters together and counts how many are in each group Map<Character, Long> freq = str.chars() .mapToObj(c -> (char) c) .collect(Collectors.groupingBy(c -> c, LinkedHashMap::new, Collectors.counting())); freq.forEach((c, count) -> System.out.println(c + ": " + count)); } }

Output

s: 3 u: 1 c: 2 e: 1

Core Logic

groupingBy plus counting() builds the same frequency map declaratively, in one expression instead of a manual loop.

How It Works
  1. 1str.chars().mapToObj(c -> (char) c) turns the string's character codes into a Stream<Character>.
  2. 2Collectors.groupingBy(c -> c, LinkedHashMap::new, Collectors.counting()) groups equal characters together and counts how many are in each group.
  3. 3Passing LinkedHashMap::new as the map factory keeps the result in first-appearance order, matching the manual version.
  4. 4freq.forEach((c, count) -> ...) prints every entry using a lambda instead of an explicit entrySet() loop.
Grouping "success" produces the same counts as the manual version: s: 3, u: 1, c: 2, e: 1.
💡

Key Point: groupingBy's three-argument form lets you choose the resulting map type — without LinkedHashMap::new, the default HashMap wouldn't guarantee this ordering.

Complexity
Time Complexity: O(n)Space Complexity: O(n)

Why: groupingBy() still visits every character once while building the map, which holds one entry per distinct character just like the manual version.

Key Concepts

StreamCollectors.groupingBy()Collectors.counting()

Related Programs