Неверная сортировка с помощью Collator с использованием Locale.SIMPLIFIED_CHINESE

Я пытаюсь заказать список стран на китайском языке, используя Locale.SIMPLIFIED_CHINESE, который, кажется, заказывает с использованием пиньинь (фонетический алфавит, который является символом, упорядочен согласно их латинской корреспондентской комбинации, от А до Я).

Но я обнаружил некоторые случаи, когда он заказывает плохо. Например:

  • Символом
  • '中' является zhong1 Символом
  • '梵' является fan4

Правильный порядок должен быть 梵 <中, но вместо этого он упорядочен по-другому.

String[] characters = new String[] {"梵", "中"};
List<String> list = Arrays.asList(characters);
System.out.println("Before sorting...");
System.out.println(list.toString());

Collator collator = Collator.getInstance(Locale.SIMPLIFIED_CHINESE);
collator.setStrength(Collator.PRIMARY);
Collections.sort(list, collator);

System.out.println("After sorting...");
System.out.println(list.toString());

Результаты этого фрагмента:

Before sorting...
[梵, 中]
After sorting...
[中, 梵]

Идя глубже, я нашел правила, которые Java применяет с Locale.SIMPLIFIED_CHINESE. Вы можете найти следующее изображение: http://postimg.org/image/4t915a7gp/full/ (обратите внимание, что 梵 после 中)

Я понял перед символом < 口 < 口 < 口 < 口, который я выделил красным цветом, все символы упорядочены в соответствии с их латинской корреспондирующей комбинацией от А до Z. Однако после < Знак 口 < 口 < 口 < 口, символы упорядочены по составу персонажа. Например, если все символы имеют одну и ту же часть (обычно левую часть символа), они группируются вместе, а не в соответствии с правилом от А до Я.

Кроме того, все символы после < 口 < < 口 < 口 < 口 менее типичные китайские символы. Таким образом, 梵 является менее общим символом, чем 中, поэтому он помещается после < 口 < 口 < 口 < 口 < 口.

Интересно, почему это решение, если оно намеренно. Но это приводит к неправильной сортировке. Я не знаю, как найти решение для этого.

Большое спасибо за ваше время!

Ответ 1

Порядок сортировки, предоставляемый коллатором в Java, основан на штрихах, необходимых для записи этого символа.

Ниже показан небольшой фрагмент, который нужно продемонстрировать. Число штрихов, взятое из Викисловарь

// the unicode character and the number of strokes
String[] characters = new String[]{
    "\u68B5 (11)", "\u4E2D (4)", 
    "\u5207 (4)", "\u5973 (3)", "\u898B (7)"
};
List<String> list = Arrays.asList(characters);
System.out.println("Before sorting...");
System.out.println(list.toString());

Collator collator = Collator.getInstance(Locale.TRADITIONAL_CHINESE);
collator.setStrength(Collator.PRIMARY);
System.out.println();
Collections.sort(list, collator);

System.out.println("After sorting...");
System.out.println(list.toString());

Выход

Before sorting...
[梵 (11), 中 (4), 切 (4), 女 (3), 見 (7)]

After sorting...
[女 (3), 中 (4), 切 (4), 見 (7), 梵 (11)]

Существует запрос на улучшение JDK-6415666 для реализации порядка сортировки в соответствии с порядком сортировки Unicode. Но, следуя информации о поддерживаемой Java 8, она не реализована в Java 8.

edit Порядок сортировки с использованием collator из icu4j -

[梵 (11), 見 (7), 女 (3), 切 (4), 中 (4)]

фрагмент кода ICU4J

import com.ibm.icu.text.Collator;
import com.ibm.icu.text.RuleBasedCollator
...
Locale locale = new Locale("zh", "", "PINYIN");
Collator collator = (RuleBasedCollator) Collator.getInstance(locale);