Find Most Frequent Character in a String in Java
Problem
The most frequent character is whichever character has the highest count once every character's occurrences have been tallied.
Given a string, find the character that appears the most times, along with its count.
Java Program
import java.util.LinkedHashMap;
import java.util.Map;
public class MostFrequentCharacter {
public static void main(String[] args) {
String str = "success";
Map<Character, Integer> freq = new LinkedHashMap<>();
for (char c : str.toCharArray()) {
freq.put(c, freq.getOrDefault(c, 0) + 1); // increment this character's running count
}
char maxChar = ' ';
int maxCount = 0;
for (Map.Entry<Character, Integer> entry : freq.entrySet()) {
if (entry.getValue() > maxCount) { // found a new highest count so far
maxChar = entry.getKey();
maxCount = entry.getValue();
}
}
System.out.println("Most frequent character: " + maxChar + " (" + maxCount + " times)");
}
}Output
Core Logic
Building the frequency map first, then scanning it once for the highest count, finds the winner in two simple passes.
- 1A
LinkedHashMap<Character, Integer>namedfreqtracks each character's count, exactly like counting character frequency. - 2
freq.getOrDefault(c, 0)reads the current count, or0if unseen, thenfreq.put(c, ...)stores the incremented count. - 3
maxCharandmaxCounttrack the best candidate seen so far while walkingentrySet(). - 4Whenever an entry's count exceeds
maxCount, bothmaxCharandmaxCountare updated to that entry.
"success", 's' ends with a count of 3 — higher than 'u', 'c', or 'e' — so it's reported as the most frequent character.Key Point: Using > rather than >= when updating the maximum means the first character to reach the highest count wins any tie, keeping the result deterministic.
Why: Building the frequency map visits every character once and holds one entry per distinct character, up to n in the worst case.
Key Concepts
Approach 2: Java 8
import java.util.Map;
import java.util.stream.Collectors;
public class MostFrequentCharacterStream {
public static void main(String[] args) {
String str = "success";
Map<Character, Long> freq = str.chars()
.mapToObj(c -> (char) c)
.collect(Collectors.groupingBy(c -> c, Collectors.counting()));
// Compares every entry by its count and keeps the largest one
Map.Entry<Character, Long> maxEntry = freq.entrySet().stream()
.max(Map.Entry.comparingByValue())
.orElseThrow();
System.out.println("Most frequent character: " + maxEntry.getKey() + " (" + maxEntry.getValue() + " times)");
}
}
Output
Core Logic
Once the frequency map exists, a stream can find its highest-valued entry directly instead of a manual running-maximum loop.
- 1
str.chars().mapToObj(c -> (char) c)turns the string's character codes into aStream<Character>. - 2
Collectors.groupingBy(c -> c, Collectors.counting())groups equal characters together and counts how many are in each group. - 3
freq.entrySet().stream().max(Map.Entry.comparingByValue())compares every entry by its count and keeps the single largest one, wrapped in anOptional. - 4
.orElseThrow()unwraps the result, since the string is known not to be empty here.
"success" produces counts for each character, and max() picks out 's': 3 as the largest entry.Key Point: Map.Entry.comparingByValue() is a ready-made comparator that compares entries purely by their value — no need to write a custom Comparator for this common case.
Why: groupingBy() still visits every character once to build the map, and max() then makes one pass over its entries to find the largest.