Home » Java » Sorting arraylist in alphabetical order(Persian)

Sorting arraylist in alphabetical order(Persian)

Posted by: admin December 28, 2021 Leave a comment

Questions:

I have a list of items in Persian and I want to sort them in alphabetical order.
As I understood java does not support sorting in Persian alphabetical correctly.

My code:

List<String> items = new ArrayList<>();
items.add("آب");
items.add("بابا");
items.add("تار");
items.add("پارک");
items.add("توت");

Collections.sort(items);

When I print this list the result will be:

آب
بابا
تار
توت
پارک

But it must be like this:

آب
بابا
پارک
تار
توت

The problem is with these letters گ چ پ ژ
How can I fix it?

Answers:

In the code of your question Java uses the unicode order to sort the Strings, and (I have to guess) this is not helpful for Persian.

To sort correctly, you can use the Collator functionality provided by Java.

Collator collator = Collator.getInstance(new Locale("fa", "IR"));
collator.setStrength(Collator.PRIMARY);
Collections.sort(items, collator);

I don’t know if Persian is supported, though.

###

This code will give expected result:

import java.util.*;

public class Main {
final static String ORDER = "ا ب پ ت ث ج چ ح خ د ذ ر ز ژ س ش ص ض ط ظ ع غ ف ق ک گ ل م ن و ه ی";


public static void main(String[] args) {
    List<String> items = new ArrayList<String>();
    items.add("آب");
    items.add("بابا");
    items.add("تار");
    items.add("پارک");
    items.add("توت");

    Collections.sort(items,  new Comparator<String>() {
        @Override
        public int compare(String o2, String o1) {
            return ORDER.indexOf(o2.charAt(0)) -  
            ORDER.indexOf(o1.charAt(0));
        }
    });

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

}

}

It sort by first letter only. To order by other letters, the compare method should be improved accordingly.

###

In case other solutions such as above ones didn’t work there, you can use this hack,

static private String prepareForArabicSort(String text) {
        return text
                .replaceAll("ی", "ي")
                .replaceAll("ک", "ك")
                .replaceAll("گ", "كی")
                .replaceAll("ژ", "زی")
                .replaceAll("چ", "جی")
                .replaceAll("پ", "بی");
}

Arrays.sort(list, (l, r) -> {
    return prepareForArabicSort(l).compareTo(prepareForArabicSort(r);
});

###

Unfortunately this is an old (since Java 1.4), but still unresolved enhancement request.
See bug-report JDK-6182989 – Collator should support the correct sort order for Persian.
But may be you can just copy the proposed code for a PersianCollator given there, and then use it like this:

Collections.sort(items, PersianCollator.persianCollator());

###

Not sure what version of Java you are using, but you could use a simple RuleBasedCollator to switch the order of the few characters that need to be switched (the rest should follow Unicode order). There is a good example in the description of the class in the API documentation.

There is also a complete example in the Java Tutorials that show how to use the RuleBasedCollator you create.

###

if you have an arrayList of objects you can use this method

first create a collator:

val collator: Collator = Collator.getInstance(Locale("fa", "IR"))
collator.strength = Collator.PRIMARY

then your list via sortedBy like this:

val sortList = items.sortedWith(compareBy (collator){ it.name})

that items is your arrayList of objects and it.name is your comparator