Back to Stream: Sorting & Comparator
Q17Question 17 of 23

Sort employees by name alphabetically (case-insensitive)

Key Concepts
  • Comparator.comparing(Employee::getName, String.CASE_INSENSITIVE_ORDER) ignores letter case
  • The two-argument comparing() takes both a key extractor and a comparator for the key
  • Without case-insensitive ordering, all uppercase names sort before all lowercase ones
  • String.CASE_INSENSITIVE_ORDER is a built-in Comparator<String> constant
  • For truly locale-correct sorting, use a Collator configured for the target locale
  • An alternative is extracting a normalised key: comparing(e -> e.getName().toLowerCase())

Definition

Sort names with `String.CASE_INSENSITIVE_ORDER` so capitals and lowercase are ordered together.
  • Two-argument comparing(keyExtractor, keyComparator) lets you sort by a key using a custom comparator.
  • String.CASE_INSENSITIVE_ORDER is a built-in comparator that ignores letter case.
  • Without it: natural String ordering puts all uppercase before all lowercase (Z before a).
  • Locale-correct: for non-English, use a Collator instead of the case-insensitive constant.
  • Alternative: comparing(e -> e.getName().toLowerCase()) normalises before comparing.

The front-desk officer at the National Bank of India wants the customer list in alphabetical order for a phone book, but some names were typed in capitals and some in small letters. Case-insensitive sorting treats "amit" and "Amit" the same.

Understanding the Concepts

Why is case-insensitive sorting needed?

Natural String ordering compares by character codes. All uppercase letters (A-Z, codes 65-90) come before all lowercase letters (a-z, codes 97-122), so "Zebra" sorts before "apple". This is clearly wrong for a human-readable alphabetical list.

How do you sort names case-insensitively?

JAVA
package com.bank.hr;

import java.util.*;
import java.util.stream.Collectors;

public class CaseInsensitiveSort {
    public static void main(String[] args) {
        List<String> names = List.of("Rajesh", "amit", "PRIYA", "kavita", "Suresh");

        List<String> sorted = names.stream()
            .sorted(String.CASE_INSENSITIVE_ORDER)
            .collect(Collectors.toList());

        System.out.println(sorted);
    }
}
TEXT
[amit, kavita, PRIYA, Rajesh, Suresh]

How do you sort Employee objects by name case-insensitively?

JAVA
List<Employee> sorted = staff.stream()
    .sorted(Comparator.comparing(Employee::getName,
        String.CASE_INSENSITIVE_ORDER))
    .collect(Collectors.toList());

How does case-insensitive compare to case-sensitive?

| Input | Case-sensitive sort | Case-insensitive sort |
|---|---|---|
| ["Zebra", "apple", "Banana"] | [Banana, Zebra, apple] | [apple, Banana, Zebra] |
| ["PRIYA", "amit", "Rajesh"] | [PRIYA, Rajesh, amit] | [amit, PRIYA, Rajesh] |

What are common mistakes?

Mistake: using natural order when names have inconsistent casing.

JAVA
// WRONG: natural order groups uppercase before lowercase
names.stream().sorted().collect(Collectors.toList());
// [PRIYA, Rajesh, Suresh, amit, kavita]  ← wrong!

// CORRECT: case-insensitive order
names.stream()
    .sorted(String.CASE_INSENSITIVE_ORDER)
    .collect(Collectors.toList());
// [amit, kavita, PRIYA, Rajesh, Suresh]  ← correct!

What about normalising with toLowerCase?

An equivalent approach extracts a normalised key.

JAVA
// Alternative: compare by lower-cased key
List<Employee> sorted = staff.stream()
    .sorted(Comparator.comparing(e -> e.getName().toLowerCase()))
    .collect(Collectors.toList());

This allocates a new lowercase string per comparison, whereas CASE_INSENSITIVE_ORDER does not. For large datasets the constant is more efficient.

When do you need a Collator instead?

Case-insensitive is still not fully locale-correct for all languages. For truly locale-aware ordering, use a Collator.

JAVA
import java.text.Collator;
import java.util.Locale;

Collator collator = Collator.getInstance(new Locale("hi", "IN"));

List<String> hindiSorted = names.stream()
    .sorted(collator)
    .collect(Collectors.toList());

What should a senior engineer know?

  • String.CASE_INSENSITIVE_ORDER is a pre-built Comparator, not a method call.
  • It works for English but may not produce correct results for Turkish, German, or other languages with special case-folding rules.
  • The two-argument Comparator.comparing(keyExtractor, keyComparator) is the idiomatic way to sort objects by a key using a custom comparator.

What are common interview follow-up questions?

  • "What is the difference between natural order and case-insensitive?" Natural order uses character codes; case-insensitive folds case.
  • "When is a Collator needed?" For locale-specific alphabetical rules.
  • "Does case-insensitive sort change the original strings?" No, it only changes the comparison logic.

Visual Overview

DIAGRAM
  Natural String order (by char code):
  A(65) B(66) ... Z(90) a(97) b(98) ... z(122)
  → "Zebra" sorts before "apple" ← wrong!

  Case-insensitive order:
  A/a → B/b → C/c → ... → Z/z
  → "apple" sorts before "Banana" before "Zebra" ← correct!

  Comparator.comparing(Employee::getName,
      String.CASE_INSENSITIVE_ORDER)

Key Takeaway

To sort names alphabetically while ignoring case I use the two-argument Comparator.comparing with the name getter and String.CASE_INSENSITIVE_ORDER as the key comparator. Without it, natural String ordering puts all uppercase before all lowercase, so "Zebra" sorts before "apple".

In my banking project at the National Bank of India this was for a staff phone book. The HR data had names in inconsistent casing from different imports, and the case-insensitive comparator fixed the ordering.

For non-English languages where case-folding rules differ, I use a Collator configured for the target locale instead of the simple case-insensitive constant. The two-argument comparing form is the idiomatic way to sort objects by a key with a custom comparator.

Remember one sentence: Comparator.comparing(getName, String.CASE_INSENSITIVE_ORDER) sorts names alphabetically regardless of letter casing.

---

Share
Use ← → arrow keys to navigate