Count Word Frequency Using HashMap in Java
Problem
Splitting a sentence into individual words and tallying each one in a map turns 'how often does this word appear' into a single pass over the split array.
Given a sentence, tally how many times each word appears using a HashMap.
Java Program
import java.util.LinkedHashMap;
import java.util.Map;
public class WordTallyHashMap {
public static void main(String[] args) {
String sentence = "cat dog cat bird dog cat";
Map<String, Integer> tally = new LinkedHashMap<>();
for (String word : sentence.split(" ")) {
tally.put(word, tally.getOrDefault(word, 0) + 1); // read-or-default, then store the incremented count
}
for (Map.Entry<String, Integer> entry : tally.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
}Output
Core Logic
Splitting the sentence on spaces first, then bumping each word's running total in a map, separates 'break it into words' from 'count them' as two clean steps.
- 1
sentence.split(" ")breaks the sentence into an array of individual words. - 2A
LinkedHashMap<String, Integer>namedtallykeeps each word's count, in first-appearance order. - 3
tally.getOrDefault(word, 0)reads a word's running count, defaulting to0on its first appearance. - 4
tally.put(word, ...)stores that count back in, incremented by one.
"cat dog cat bird dog cat", "cat" ends with a tally of 3, "dog" with 2, and "bird" with 1.Key Point: Using a LinkedHashMap instead of a plain HashMap is what keeps the printed order matching the order each word first showed up — a plain HashMap would tally the same counts but print them in an unpredictable order.
Why: Every word is visited once to update its tally, and the map holds one entry per distinct word, up to n in the worst case.
Key Concepts
Approach 2: Java 8
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class WordTallyStream {
public static void main(String[] args) {
String sentence = "cat dog cat bird dog cat";
// Groups equal words together and counts how many are in each group
Map<String, Long> tally = Arrays.stream(sentence.split(" "))
.collect(Collectors.groupingBy(word -> word, LinkedHashMap::new, Collectors.counting()));
tally.forEach((word, count) -> System.out.println(word + ": " + count));
}
}
Output
Core Logic
Streaming the split words and grouping equal ones together with counting() builds the same tally map in one line, without a manual getOrDefault loop.
- 1
Arrays.stream(sentence.split(" "))turns the split words into aStream<String>. - 2
Collectors.groupingBy(word -> word, LinkedHashMap::new, Collectors.counting())groups equal words together and counts how many are in each group. - 3Passing
LinkedHashMap::newas the map factory keeps the tally in first-appearance order, matching the primary approach'sLinkedHashMapchoice. - 4The result is a
Map<String, Long>— the count is aLong, not anint, sincecounting()always produces one.
"cat dog cat bird dog cat"'s words produces the same tally as the manual version: cat: 3, dog: 2, bird: 1, in first-appearance order.Key Point: groupingBy + counting() is the idiomatic modern-Java way to build a frequency map — it reads as 'group by identity, then count', with no manual increment logic at all.
Why: groupingBy() still visits every word once while building the map, which holds one entry per distinct word just like the manual version.