Java ProgramsStringsCount Words in a String

Count Words in a String in Java

beginner·  Strings  ·  String

Problem

Words in a sentence are typically separated by whitespace, so counting them means counting how many whitespace-separated tokens the string splits into.

Given a sentence, count how many words it contains.

Input
The quick brown fox
Output
Words: 4

Java Program

Java
public class CountWords { public static void main(String[] args) { String str = "The quick brown fox"; String trimmed = str.trim(); // Splitting on a run of whitespace avoids counting empty tokens between words String[] words = trimmed.isEmpty() ? new String[0] : trimmed.split("\\s+"); System.out.println("Words: " + words.length); } }

Output

Words: 4

Core Logic

Trimming the sentence and splitting on runs of whitespace turns the word count into the length of the resulting array.

How It Works
  1. 1str.trim() removes any leading or trailing whitespace, so a stray space doesn't create an empty extra token.
  2. 2trimmed.split("\\s+") splits on one or more whitespace characters, so multiple spaces between words don't create empty tokens either.
  3. 3The number of elements in the resulting array is exactly the number of words.
  4. 4An empty trimmed string is handled as a special case, since splitting it would otherwise report one word instead of zero.
For "The quick brown fox", splitting on whitespace produces ["The", "quick", "brown", "fox"] — four words.
💡

Key Point: Splitting on " " alone (a single space) would count an empty string between two consecutive spaces as its own word — "\\s+" collapses any run of whitespace into a single split point.

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

Why: split() has to scan the whole string once to find whitespace boundaries, and it allocates a new String for every word found.

Key Concepts

String.trim()String.split()regex

Approach 2: Manual Whitespace Scan

Java
public class CountWordsManual { public static void main(String[] args) { String str = "The quick brown fox"; int count = 0; boolean inWord = false; // Count only the transitions from whitespace into the start of a word for (char c : str.toCharArray()) { if (!Character.isWhitespace(c)) { if (!inWord) count++; inWord = true; } else { inWord = false; } } System.out.println("Words: " + count); } }

Output

Words: 4

Core Logic

Instead of building an array of words, a single pass can just count the transitions from whitespace into a word.

How It Works
  1. 1A boolean inWord flag tracks whether the scan is currently inside a word.
  2. 2Character.isWhitespace(c) checks each character; a non-whitespace character starting a new word increments count.
  3. 3inWord is set to true while inside a word and reset to false at the first whitespace character after it.
  4. 4Consecutive whitespace characters don't trigger extra increments, since count only goes up on the transition into a word.
Scanning "The quick brown fox" character by character increments count at 'T', 'q', 'b', and 'f' — the start of each word.
💡

Key Point: This never allocates an array of the individual words, so for very long text it uses less memory than the split-based version while still running in a single pass.

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

Why: The scan tracks word boundaries with a single boolean flag, never allocating an array of the individual words.

Key Concepts

Character.isWhitespace()boolean flagfor-each loop

Approach 3: Java 8

Java
import java.util.Arrays; public class CountWordsStream { public static void main(String[] args) { String str = "The quick brown fox"; // filter() drops empty tokens, covering the empty-string edge case in one step long count = Arrays.stream(str.trim().split("\\s+")) .filter(w -> !w.isEmpty()) .count(); System.out.println("Words: " + count); } }

Output

Words: 4

Core Logic

Streaming the split tokens and filtering out any empty ones counts the words in a single expression, without a separate empty-string special case.

How It Works
  1. 1str.trim().split("\\s+") splits the trimmed string the same way the primary approach does.
  2. 2Arrays.stream(...) turns the resulting array into a Stream<String>.
  3. 3.filter(w -> !w.isEmpty()) drops any empty token, which covers the case where the trimmed string was empty to begin with — split() on an empty string returns an array containing one empty token, not zero.
  4. 4.count() returns how many tokens survived the filter, as a long.
For "The quick brown fox", streaming ["The", "quick", "brown", "fox"] and filtering out empties (there are none here) still counts 4.
💡

Key Point: The filter() step replaces the primary approach's explicit trimmed.isEmpty() ? new String[0] : ... check with a single condition that works whether or not the trimmed string was empty.

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

Why: split() still scans the whole string once and allocates a token array, which the stream then wraps and filters.

Key Concepts

StreamArrays.stream()filter()

Related Programs