TechByteByByte

Count Uppercase and Lowercase Letters in a String - Java

An easy QA/automation coding interview question: count Uppercase and Lowercase Letters in a String, with a full Java walkthrough, dry run, and common interviewer follow-ups.

#Strings#Loops#Character Methods#Easy#Java

Category: Easy | Concepts used: Character classification, ASCII vs Unicode representations


Problem Statement

Given a string, count how many uppercase letters and how many lowercase letters it contains.

Input : "Hello World"     Output: Uppercase = 2, Lowercase = 8
Input : "12345"            Output: Uppercase = 0, Lowercase = 0

Examples (with edge scenarios)

#InputUppercaseLowercaseWhy
1"Hello World"28H, W are uppercase; rest are lowercase
2""00Empty string contains nothing
3"12345!@#"00Digits/symbols are neither
4"ABC"30All uppercase letters
5"abc"03All lowercase letters

โš ๏ธ Common Beginner Mistake

MistakeImpactFix
Checking only ASCII ranges (ch >= 'A' && ch <= 'Z')Fails to detect international capital characters like ร€ or ร–Use Javaโ€™s built-in Character.isUpperCase()
Assuming characters that arenโ€™t uppercase must be lowercaseIncorrectly counts spaces and digits as lowercase lettersAlways use an explicit else if for lowercase checks

Before You Code: Clarify the Contract

Before choosing an algorithm, confirm how null and empty strings should behave, whether comparison is case-sensitive, and whether spaces or punctuation count. Java char values are UTF-16 code units, not always complete human-visible Unicode characters, so international text may require code points or grapheme-aware libraries.

Analogy: Sorting Mail by Envelope Size

Imagine you are sorting incoming mail. You have two target buckets: one for large manila envelopes (Uppercase) and one for small letter envelopes (Lowercase):

  • You inspect each package one by one.
  • If itโ€™s a large envelope, put it in the โ€œlargeโ€ bucket (upper++).
  • If itโ€™s a small envelope, put it in the โ€œsmallโ€ bucket (lower++).
  • If you pull out a package that is a package box, tube, or poster (numbers, spaces, punctuation), it doesnโ€™t fit either category. You simply stack it to the side and ignore it!

Solution 1 โ€” Manual ASCII Range Check

This approach checks if the numeric representation of the character falls within the uppercase or lowercase ASCII block.

Intuition

Behind the scenes, every character is represented by a number. Uppercase characters sit between decimal 65 (A) and 90 (Z). Lowercase letters sit between 97 (a) and 122 (z).

public class CaseCounterManual {
    public static void countCase(String str) {
        if (str == null) {
            System.out.println("Uppercase = 0, Lowercase = 0");
            return;
        }

int upper = 0, lower = 0;
        for (int i = 0; i < str.length(); i++) {
            char ch = str.charAt(i);
            if (ch >= 'A' && ch <= 'Z') {
                upper++;
            } else if (ch >= 'a' && ch <= 'z') {
                lower++;
            }
            // All non-alphabetic characters are automatically skipped
        }
        System.out.println("Uppercase = " + upper + ", Lowercase = " + lower);
    }

public static void main(String[] args) {
        countCase("Hello World"); // Uppercase = 2, Lowercase = 8
        countCase("12345!@#");     // Uppercase = 0, Lowercase = 0
    }
}

Output:

Uppercase = 2, Lowercase = 8
Uppercase = 0, Lowercase = 0

Dry Run (str = โ€œHi!โ€)

i = 0: 'H' -> within 'A'-'Z' -> upper = 1
i = 1: 'i' -> within 'a'-'z' -> lower = 1
i = 2: '!' -> neither range -> ignored
Final Output: Uppercase = 1, Lowercase = 1

Solution 2 โ€” Using Character.isUpperCase() / isLowerCase() (Preferred)

This approach uses built-in helper methods which support Unicode characters.

Intuition

Rather than relying on raw English ASCII limits, we use the JVM standard methods. This makes the code shorter, more readable, and robust against international charsets.

public class CaseCounterBuiltIn {
    public static void countCase(String str) {
        if (str == null) {
            System.out.println("Uppercase = 0, Lowercase = 0");
            return;
        }

int upper = 0, lower = 0;
        for (char ch : str.toCharArray()) {
            if (Character.isUpperCase(ch)) {
                upper++;
            } else if (Character.isLowerCase(ch)) {
                lower++;
            }
        }
        System.out.println("Uppercase = " + upper + ", Lowercase = " + lower);
    }

public static void main(String[] args) {
        countCase("Hello World"); // Uppercase = 2, Lowercase = 8
        countCase("ABC");          // Uppercase = 3, Lowercase = 0
    }
}

Output:

Uppercase = 2, Lowercase = 8
Uppercase = 3, Lowercase = 0

๐Ÿ“Š Visual Flowchart

graph TD
    Start["Input String S"] --> Empty{"S is null or empty?"}
    Empty -->|Yes| End["Print: Upper=0, Lower=0"]
    Empty -->|No| Init["Initialize upper=0, lower=0"]
    Init --> Loop{"i < S.length()?"}
    Loop -->|Yes| Fetch["ch = S.charAt(i)"]
    Fetch --> IsUpper{"Character.isUpperCase(ch)?"}
    IsUpper -->|Yes| IncUpper["upper++"]
    IsUpper -->|No| IsLower{"Character.isLowerCase(ch)?"}
    IsLower -->|Yes| IncLower["lower++"]
    IsLower -->|No| IncLoop["i++"]
    IncUpper --> IncLoop
    IncLower --> IncLoop
    IncLoop --> Loop
    Loop -->|No| Print["Print: upper, lower"]
    Print --> End

Interviewer Insights

This is a typical QA automation question assessing basic logic paths.

Follow-up questions you might get:

  • โ€œWhat is the main advantage of Solution 2 over Solution 1?โ€ โ†’ Solution 1 only works for basic Latin/English characters. Solution 2 evaluates Unicode properties, so it correctly counts uppercase/lowercase characters from languages such as Spanish, French, German, or Cyrillic characters.
  • โ€œWhy is toCharArray() used in Solution 2?โ€ โ†’ toCharArray() makes the loop syntax cleaner by returning a raw array of characters. Note that this creates a temporary char array copy in memory, so for memory-critical scenarios, str.charAt(i) inside a standard index loop is slightly more efficient.

Quick Recap

ApproachUnicode Support?Time ComplexitySpace ComplexityInterview Signal
Manual ASCII CheckNo (English only)(O(N))(O(1))Demonstrates low-level ASCII conversion understanding
Character HelpersYes(O(N))(O(1))Clean, robust, internationalized, standard production code
Author
TechByteByByte Editorial Team
Reviewed by
TechByteByByte Admin
Published
Last reviewed