Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Java collation: display order and distinct stored labels

Last updated: 29 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

Collation compares natural-language strings under a locale and strength policy; comparator equality can group labels that String.equals still treats as different.

Download Java source kit

Java 8+. The program uses JDK classes and requires no preview flags.

Sorting is not identifier equality

A customer directory can sort labels without treating every case or accent difference as a new primary position. That is a presentation decision. An account identifier still needs its own exact or normalized equality contract; using the directory comparator as a map-key rule can merge accounts that should remain distinct.

The program uses a French collator at primary strength. It compares two labels that differ by an accent and then shows the membership effect in TreeSet. The second set adds a UTF-16 tie-break so comparator-equivalent spellings remain separate values. The set is ordered by that combined rule, not just by the collator.

The locale is explicit. A default-locale comparison can change when the application moves to a machine with another language setting. Locale data can also change across JDK releases. Store stable identifiers independently of the user’s display order, and state the runtime when a test asserts a particular ordering.

Treat configuration as owned state

Collator configuration includes strength and decomposition mode. Configure an instance before using it in a sorted collection, then keep that rule fixed for the collection’s lifetime. Changing a comparator’s behavior after insertion can invalidate search assumptions even if no label object changed.

Working program

Java
import java.text.Collator;
import java.util.*;
public class CustomerDirectoryOrder {
    public static void main(String[] args){
        Collator french=Collator.getInstance(Locale.FRENCH);french.setStrength(Collator.PRIMARY);
        String first="cote",second="c\u00f4te";
        TreeSet<String> grouped=new TreeSet<>((a,b)->french.compare(a,b));
        grouped.add(first);grouped.add(second);
        Comparator<String> distinct=(a,b)->{int compared=french.compare(a,b);return compared!=0?compared:a.compareTo(b);};
        TreeSet<String> labels=new TreeSet<>(distinct);labels.add(first);labels.add(second);
        System.out.println(french.compare(first,second)==0);
        System.out.println(grouped.size());System.out.println(labels.size());
    }
}

Output

Output
true
1
2

Costs and boundaries

A comparison examines the strings under the chosen locale rules. Sorting performs O(n log n) comparisons for n labels, with text-processing costs inside each comparison. A tie-break preserves distinct spellings but does not create a universal cross-version collation order.

Common Mistakes

  • Comparator equality can collapse TreeSet membership.
  • The machine’s default locale is not an explicit application policy.
  • Do not change comparator settings after insertion.

Read next

Ordered membership, Stored text policy.

java
collation-policy
Storage details