Comparing Strings in Java
compareTo lexicographic order and case sensitivity.
["apple", "Zebra"] and Java proudly answers [Zebra, apple]. Z before a? Java isn't bad at the alphabet — it just counts differently than you do.A three-way answer
a.compareTo(b) answers "who comes first?" with a number: negative → a first, zero → equal, positive → a after b. Only the sign is guaranteed, not the exact value.
"apple".compareTo("banana"); // negative
"pear".compareTo("pear"); // 0
"pear".compareTo("apple"); // positiveChar by char, by number
Java walks both Strings and stops at the first different character, comparing their UTF-16 numbers. Uppercase A–Z are 65–90 and lowercase a–z are 97–122, so every uppercase letter sorts before every lowercase one.
"Zebra".compareTo("apple");
// 'Z' (90) vs 'a' (97): negativeNot just -1, 0, 1
What does this print?
System.out.println("cat".compareTo("car"));
System.out.println("app".compareTo("apple"));1 -12 -22 -1-2 2
Show the answer
2 and -2. 't' (116) minus 'r' (114) is 2. When one String is a prefix of the other, the result is the length difference: 3 − 5 = −2.
Checking the order
if (a.compareTo(b) == -1) {
// a first?
}The value may be -2 or -17. This silently fails.
if (a.compareTo(b) < 0) {
// a first
}Test the sign, never an exact number.
Sorting mixed case
Arrays.sort uses compareTo (natural order). What prints?
String[] w = {"cherry", "Banana", "apple"};
Arrays.sort(w);
System.out.println(Arrays.toString(w));[apple, Banana, cherry][Banana, apple, cherry][cherry, Banana, apple]
Show the answer
[Banana, apple, cherry]. 'B' (66) is smaller than 'a' (97), so the capitalized word jumps to the front.
Ignoring case
Want human-friendly order? Use compareToIgnoreCase, or pass the ready-made Comparator String.CASE_INSENSITIVE_ORDER to a sort. Note: equalsIgnoreCase returns a boolean, so it can't be used as a Comparator.
var names = new ArrayList<>(
List.of("bob", "Alice", "Carl"));
names.sort(String.CASE_INSENSITIVE_ORDER);
// [Alice, bob, Carl]In real projects
Contact lists, product catalogs and file browsers all sort text. Natural order puts "Zoe" before "adam" — users file that as a bug. Use case-insensitive order, and for real languages with accents (é, ü), java.text.Collator sorts the way a dictionary would.
Key takeaways
- Negative: this comes first; 0: equal; positive: this comes after
- The sign matters, not the exact number
- Uppercase A-Z (65-90) sort before lowercase a-z (97-122)
- Use compareToIgnoreCase or String.CASE_INSENSITIVE_ORDER to ignore case
Uppercase and lowercase ASCII letters differ by exactly 32 — a single bit. 'a' - 'A' is 32, and so is 'z' - 'Z'.
Practice questions
What does this print?
System.out.println("apple".compareTo("banana") < 0);
System.out.println("Zebra".compareTo("apple") < 0);- true false
- true true
- false true
- false false
Check your answer
true true. 'a' comes before 'b', so the first is negative. 'Z' is 90 and 'a' is 97, so "Zebra" also comes before "apple".
Fill the blank so the list ends up as [Alice, bob, Carl].
var names = new ArrayList<>(
List.of("bob", "Alice", "Carl"));
names.sort(___);- String.CASE_INSENSITIVE_ORDER
- String::compareTo
- Comparator.reverseOrder()
- String::equalsIgnoreCase
Check your answer
String.CASE_INSENSITIVE_ORDER. Natural order (String::compareTo) gives [Alice, Carl, bob] because uppercase sorts first. CASE_INSENSITIVE_ORDER compares as if case did not exist. equalsIgnoreCase returns boolean, so it is not a Comparator.