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

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

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

  • Символ '中' - Чжун1
  • Символ '梵' - фанат4

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

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. Вы можете найти на следующем изображении: https://postimg.cc/image/4t915a7gp/full/ (Обратите внимание, что 梵 стоит после 中)

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

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

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


person elegarpes    schedule 12.11.2015    source источник
comment
Вы пробовали использовать icu4j?   -  person fge    schedule 12.11.2015
comment
Я пробовал pinyin4j, и порядок у них хороший. icu4j еще не пробовал. Но мой вопрос о том, почему Oracle сортирует по этим правилам, может быть, это ошибка, о которой нужно сообщить, или, может быть, есть другой способ использования Java API для сортировки с соглашениями пиньинь. В моей компании сложно добавлять новые библиотеки из-за ненадежности. Спасибо за поддержку!   -  person elegarpes    schedule 12.11.2015


Ответы (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, он не реализован на Яве 8.

изменить Порядок сортировки с использованием подборщика из 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);
person SubOptimal    schedule 15.01.2016