Converting Lowercase to Uppercase in Java: A Simple Implementation

In Java, convert a string to uppercase with String.toUpperCase(). That is the correct answer in almost every case: "hello".toUpperCase() returns "HELLO". Strings are immutable, so the method returns a new string and leaves the original unchanged.

This page gives the complete class, the manual character-array implementation for when you are asked to write one by hand, the locale bug that catches production code, and a comparison of the methods that ignore case.

Converting text rather than writing code? The free case converter handles UPPERCASE, lowercase, camelCase, PascalCase, snake_case and seven more styles in one click — useful when renaming identifiers.

The built-in method

public class UppercaseDemo {
    public static void main(String[] args) {
        String text = "hello world";
        System.out.println(text.toUpperCase());   // HELLO WORLD
        System.out.println(text.toLowerCase());   // hello world
        System.out.println(text);                 // hello world
    }
}

The third line is the point: text is unchanged. If you want to keep the result, assign it back: text = text.toUpperCase();

The locale trap

toUpperCase() with no argument uses the default locale of the machine running the code. On a Turkish system, the uppercase of i is İ rather than I, so a case conversion used for a comparison or a lookup key silently produces a different result than it does on an English system.

String s = "title";
System.out.println(s.toUpperCase());                 // depends on the machine
System.out.println(s.toUpperCase(Locale.ROOT));      // always TITLE
System.out.println(s.toUpperCase(Locale.ENGLISH));   // always TITLE

The rule. Use toUpperCase(Locale.ROOT) whenever the result feeds a comparison, a map key, a protocol value or a file name. Use the no-argument version only when the text is being shown to a person in their own language. This is one of the most common quiet bugs in internationalized Java.

Writing it by hand

Interview questions and coursework often ask for the conversion without the built-in method. The character-array version is the usual answer:

public class ManualUppercase {

    public static String toUpperCaseManual(String text) {
        if (text == null) {
            return null;
        }
        char[] chars = text.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            if (chars[i] >= 'a' && chars[i] <= 'z') {
                chars[i] = (char) (chars[i] - 'a' + 'A');
            }
        }
        return new String(chars);
    }

    public static void main(String[] args) {
        System.out.println(toUpperCaseManual("hello world"));
        // HELLO WORLD
    }
}

Two things to notice. The method is named for what it does — a method called convertToLowercase that returns uppercase is a bug waiting to happen, and it appears in a surprising number of published examples. And the null guard prevents a NullPointerException on the first line.

What the manual version cannot do

InputManual versiontoUpperCase()
helloHELLOHELLO
caféCAFéCAFÉ
straßeSTRAßESTRASSE
ελληνικάunchangedΕΛΛΗΝΙΚΑ

The ASCII range covers 26 letters. Everything else — accented Latin, Greek, Cyrillic — falls outside the a to z test and passes through untouched. The German sharp s is a further case: its uppercase form is two characters, which a char[] of fixed length cannot represent at all. Write the manual version to demonstrate the idea; ship the built-in one.

Three other ways

ApproachCodeWhen
StringBuildernew StringBuilder(s).reverse() style buildingAssembling a string in pieces
Character.toUpperCaseCharacter.toUpperCase(c)One character at a time
Streamss.chars().mapToObj(c -> String.valueOf(Character.toUpperCase((char) c)))Inside a stream pipeline
First letter onlys.substring(0,1).toUpperCase() + s.substring(1)Capitalizing a name

Character.toUpperCase(char) has the same limit as the manual version for characters outside the Basic Multilingual Plane, because a char is 16 bits. For full correctness on all of Unicode, use the String method rather than the Character one.

Comparing strings without caring about case

String a = "Hello";
String b = "HELLO";

System.out.println(a.equals(b));            // false
System.out.println(a.equalsIgnoreCase(b));  // true
System.out.println(a.compareToIgnoreCase(b)); // 0

Prefer equalsIgnoreCase to a.toUpperCase().equals(b.toUpperCase()). It is clearer, it avoids allocating two throwaway strings, and it does not depend on the default locale.

The same job elsewhere

Python uses .upper(), with the same immutability rule and the same Unicode subtleties — see converting lowercase to uppercase in Python. JavaScript uses toUpperCase(). Excel uses =UPPER(A1), covered in changing case in Excel. And when the text is not going through code at all, an online converter is faster than any of them.

Naming conventions in Java

Case is not only a string operation in Java; it is also a convention that the compiler does not enforce but every reader expects:

ElementConventionExample
ClassPascalCaseUppercaseDemo
Method and variablecamelCasetoUpperCaseManual
ConstantCONSTANT_CASEMAX_LENGTH
Packageall lowercasecom.example.text

Java is case-sensitive, so userName and username are two different identifiers. A single wrong capital is a compile error, not a style issue.

Renaming identifiers? The upper lower case converter produces camelCase, PascalCase, snake_case, kebab-case and CONSTANT_CASE from any text, plus the ordinary writing styles. Free, no sign-up.

Frequently asked questions

How do I convert a string to uppercase in Java?

Call toUpperCase() on the string. It returns a new string, so assign the result if you want to keep it.

Does toUpperCase change the original string?

No. Java strings are immutable. The method returns a new string and the original is unchanged.

Why should I pass Locale.ROOT to toUpperCase?

Because the no-argument version uses the machine default locale. On a Turkish system the uppercase of i is İ, which breaks comparisons and lookup keys. Pass Locale.ROOT whenever the result is not being shown to a person.

How do I convert to uppercase without using toUpperCase?

Convert the string to a char array and add the difference between 'A' and 'a' to each character in the a-to-z range. It works for plain English only.

Why does the manual method fail on accented letters?

Because the test only covers the ASCII range 'a' to 'z'. Accented Latin, Greek and Cyrillic characters fall outside it and are returned unchanged.

How do I compare two strings ignoring case?

Use equalsIgnoreCase. It is clearer than converting both strings, avoids two allocations, and does not depend on the default locale.

How do I capitalize just the first letter?

Use s.substring(0,1).toUpperCase() + s.substring(1), after checking that the string is not empty.

Is Java case-sensitive?

Yes. Class names, method names and variables are all case-sensitive, so userName and username are different identifiers.

The short version

Use toUpperCase(), and pass Locale.ROOT whenever the result is compared rather than displayed. Write the char-array version only to show that you understand ASCII, and never name a method for the opposite of what it does. For comparisons, equalsIgnoreCase beats converting both sides.

Next Post