Java Programs›Strings›Count Vowels and Consonants in a String

Count Vowels and Consonants in a String in Java

beginner·  Strings  ·  String

Problem

Vowels are the letters a, e, i, o, and u; every other letter is a consonant.

Given a string, count how many vowels and how many consonants it contains.

Input
Java Programming
Output
Vowels: 5, Consonants: 10

Java Program

Java
public class VowelConsonantCount { public static void main(String[] args) { String str = "Java Programming"; int vowels = 0, consonants = 0; String vowelSet = "aeiouAEIOU"; // Scan each character once for (char c : str.toCharArray()) { if (Character.isLetter(c)) { // skip spaces and punctuation if (vowelSet.indexOf(c) != -1) vowels++; // found in the vowel set else consonants++; // any other letter is a consonant } } System.out.println("Vowels: " + vowels + ", Consonants: " + consonants); } }

Output

Vowels: 5, Consonants: 10

Core Logic

One pass through the string is enough — check each letter against a small set of vowels and bucket it accordingly.

How It Works
  1. 1str.toCharArray() converts the string into a char[] so it can be scanned one character at a time.
  2. 2Character.isLetter(c) filters out spaces and punctuation, so only actual letters are counted.
  3. 3For each letter, vowelSet.indexOf(c) checks whether it appears in "aeiouAEIOU".
  4. 4A match increments the vowels counter; anything else increments consonants.
  5. 5After the loop, both counters hold the final vowel and consonant totals.
For "Java Programming", the scan finds 5 vowels and 10 consonants.
💡

Key Point: Including both cases in vowelSet (aeiouAEIOU) avoids a separate call to toLowerCase() for every character.

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

Why: Each character is visited once, and only the two running counters are kept regardless of string length.

Key Concepts

toCharArray()Character.isLetter()for-each loop

Approach 2: Java Streams

Java
public class VowelConsonantCountStream { public static void main(String[] args) { String str = "Java Programming"; String vowelSet = "aeiouAEIOU"; // Count letters that appear in the vowel set long vowels = str.chars() .filter(Character::isLetter) .filter(c -> vowelSet.indexOf(c) != -1) .count(); // Count letters that don't appear in the vowel set long consonants = str.chars() .filter(Character::isLetter) .filter(c -> vowelSet.indexOf(c) == -1) .count(); System.out.println("Vowels: " + vowels + ", Consonants: " + consonants); } }

Output

Vowels: 5, Consonants: 10

Core Logic

The same classification can be expressed as a stream pipeline instead of a loop — filter for letters, then split into vowels and consonants.

How It Works
  1. 1str.chars() returns an IntStream of the string's character codes.
  2. 2.filter(Character::isLetter) keeps only letters, dropping spaces and punctuation, just like the manual version's check.
  3. 3A second .filter() splits the stream into vowels (found in vowelSet) or consonants (not found).
  4. 4.count() reduces each filtered stream down to a single long total.
Filtering "Java Programming" twice — once for vowels, once for consonants — produces 5 and 10 respectively.
💡

Key Point: This runs the string through two separate stream pipelines, so for very large strings the single-pass loop is actually more efficient — the stream version trades a bit of performance for readability.

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

Why: Each filter-and-count pipeline still scans every character once, and count() reduces straight down to a single long without collecting anything.

Key Concepts

Streamchars()filter()count()

Interview Questions

Why check Character.isLetter before testing for a vowel?

Without it, spaces, digits and punctuation would fall into the "not a vowel" branch and be counted as consonants. "Java Programming" would report 11 consonants instead of 10 because of the space.

How do you count vowels and consonants with a stream?

Filter the letters first, then partition them: str.chars().filter(Character::isLetter).mapToObj(c -> (char) c).collect(Collectors.partitioningBy(c -> "aeiouAEIOU".indexOf(c) >= 0, Collectors.counting())) gives both counts in one map.

Learn the Concept

Related Programs