beginnerString ProblemsJava

Convert a String to Uppercase Without Built-in Methods

Return the uppercase form of a string using only character arithmetic, not String.toUpperCase().

Quick Answer

For each character, check whether it lies between 'a' and 'z'. If it does, subtract 32 from its code to get the matching uppercase letter, because 'a' - 'A' is 32 in ASCII. Leave every other character untouched and join the results.

Problem Statement

Given a string, return a new string with every lowercase letter converted to uppercase, but without calling String.toUpperCase() or Character.toUpperCase(). You must do the conversion using character arithmetic only.

Only the letters a-z are affected. Uppercase letters, digits, spaces and punctuation are copied to the output exactly as they appear. For example, "hello" becomes "HELLO" and "Java 8!" becomes "JAVA 8!".

Input: A single string s.

Output: The string with all lowercase letters converted to uppercase.

Examples

Example 1
Input:  "hello"
Output: "HELLO"

Each of h, e, l, l, o is shifted up by 32 in ASCII to H, E, L, L, O.

Example 2
Input:  "Java 8!"
Output: "JAVA 8!"

The lowercase a, v, a become A, V, A; the J, space, 8 and ! stay as they are.

Constraints

  • 0 <= s.length() <= 10000
  • Do not use toUpperCase(); only arithmetic on char values

Think Before You Code

Reveal the questions to ask yourself first
  • What is the numeric difference between 'a' and 'A' in ASCII?
  • How do you test that a character is a lowercase letter, and only then convert it?
  • Which characters must you leave completely unchanged?

Hints

Open them one at a time — try after each before revealing the next.

Hint 1
In ASCII, lowercase letters sit exactly 32 positions after their uppercase counterparts: `'a' == 97`, `'A' == 65`.
Hint 2
Only convert a character when `c >= 'a' && c <= 'z'`. Everything outside that range is copied as-is.
Hint 3
To convert, compute `(char)(c - 32)` and append it; otherwise append the original `c`.

Approach

Reveal the step-by-step approach

Rebuild the string one character at a time.

  1. Create an empty StringBuilder.
  2. For each character c:
    • If c is in the range 'a' to 'z', append (char)(c - 32).
    • Otherwise append c unchanged.
  3. Return the assembled string.

Subtracting 32 works because the uppercase and lowercase Latin letters are laid out in the same order in ASCII, a fixed 32 apart.

Dry Run

Walk through the example step by step

Converting "Java 8!":

index | char | in a..z? | appended
------+------+----------+---------
0     | J    | no       | J
1     | a    | yes      | (char)('a'-32) = A
2     | v    | yes      | V
3     | a    | yes      | A
4     | ' '  | no       | ' '
5     | 8    | no       | 8
6     | !    | no       | !
result: "JAVA 8!"

Solution

Reveal the full Java solution
public class ToUpperManual {
    public static String toUpper(String s) {
        StringBuilder sb = new StringBuilder(s.length());
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c >= 'a' && c <= 'z') {
                sb.append((char) (c - 32));
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        System.out.println(toUpper("hello"));   // HELLO
        System.out.println(toUpper("Java 8!")); // JAVA 8!
    }
}

The only characters that change are those between 'a' and 'z'. For each of them, subtracting 32 from the character code lands exactly on the matching uppercase letter. The explicit (char) cast is needed because subtracting an int from a char promotes the expression to int.

All other characters — already-uppercase letters, digits, spaces, symbols — are simply appended unchanged, so the output preserves everything except lowercase letters' case.

Time: O(n) where n is the length of the stringSpace: O(n) for the resulting string

Common Mistakes

  • Forgetting the range check and shifting every character by 32, corrupting digits and symbols.
  • Omitting the `(char)` cast, so the append adds an int code point or fails to compile as intended.

Edge Cases to Test

  • An empty string returns an empty string.
  • A string that is already uppercase (like "ABC") is returned unchanged.
  • Non-English Unicode letters are not handled by the 32-offset and stay as-is.

Interview Follow-Ups

  • How would you write the reverse — lowercasing without built-in methods?
  • Why does the ASCII 32-offset trick break for accented or non-Latin letters?

Practising for Java interviews?

CodeBegun's Java Full Stack with AI program builds this problem-solving muscle with mentor review and mock interviews.

Explore the Java Full Stack program →
Chat with us