20

I want to sort an ArrayList<String> but the problem is my native language characters - my alphabet is like this: a, ą, b, c, č, d, e, f ... z, ž. As you see z character is second from the end and ą is second in alphabet, so after I sort my array it is sorted incorrectly. All my native language characters are moved to the end of array. Example:

package lt;

import java.util.ArrayList;
import java.util.Collections;

public class test {
    public static void main(String[] args) {
        List<String> items = new ArrayList<>();
        items.add("bbc");
        items.add("ąbc");
        items.add("abc");
        items.add("zzz");

        System.out.println("Unsorted: ");
        for(String str : items) {
            System.out.println(str);
        }

        Collections.sort(items);
        System.out.println();

        System.out.println("Sorted: ");
        for(String str : items) {
            System.out.println(str);
        }
    }
}

Output:

Unsorted: 
bbc
ąbc
abc
zzz

Sorted: 
abc
bbc
zzz
ąbc

Should be:

Sorted:
abc
ąbc
bbc
zzz
Minutis
  • 1,193
  • 1
  • 17
  • 47

2 Answers2

23

You should use Collator class.

For example

Locale lithuanian = new Locale("lt_LT");
Collator lithuanianCollator = Collator.getInstance(lithuanian);

And then sort the collection using this collator

Collections.sort(theList, lithuanianCollator);
Sean Reilly
  • 21,526
  • 4
  • 48
  • 62
Vic
  • 21,473
  • 11
  • 76
  • 97
  • My country is Lithuania, and language is Lithuanian, what should I do, because if I am correct my Language is not supported by Locale class? – Minutis Feb 13 '12 at 13:39
  • 3
    This answer is correct, but there's no need to create a Comparator — Collator is already an instance of Comparator. Collections.sort(myList, Collator.getInstance(Locale.FRENCH)); is complete code. – Sean Reilly Feb 13 '12 at 13:43
  • 1
    `Collator` **is-a** `Comparator` by design. Creating another `Comparator` is unecessary. – Buhake Sindi Feb 13 '12 at 13:44
  • 3
    If your language isn't supported by Locale, then you're in trouble. Fortunately, according to this: http://www.oracle.com/technetwork/java/javase/javase7locales-334809.html Lithuanian is supported by Locale in java 7. Since there isn't a constant, you'll need to construct an instance of Locale yourself: Locale lithuanian = new Locale("lt_LT"); – Sean Reilly Feb 13 '12 at 13:46
  • @SeanReilly, Elite - thanks, I didn't know it. Minutis - please see Sean's response. – Vic Feb 13 '12 at 13:48
  • @SeanReilly thanks, I found it out, but this is what I did, so you're right. – Minutis Feb 13 '12 at 13:50
  • Why wouldn’t you be using the ICU classes if you’re dealing with Unicode? There at least you can depend on things. – tchrist Feb 15 '12 at 14:35
5

You can use Collator to do locale sensitive String comparisions.

Thomas
  • 87,414
  • 12
  • 119
  • 157
Kris
  • 5,714
  • 2
  • 27
  • 47