使用Java Collat​​or进行区分大小写的订单

时间:2013-09-12 09:55:22

标签: java string sorting localization collation

我试图了解区分大小写的订单应该如何使用Java Collator

this example中,以下字符串使用所有强度在法语区域设置中排序(为了说明目的,我在数据集中添加了一些额外的字符串):

[Äbc, äbc, Àbc, àbc, Abc, abc, ABC] - Original Data
[Äbc, äbc, Àbc, àbc, Abc, abc, ABC] Primary
[Abc, abc, ABC, Àbc, àbc, Äbc, äbc] Secondary
[abc, Abc, ABC, àbc, Àbc, äbc, Äbc] Tertiary

Case kicks in only with Tertiary Collation Strength  : 
[CACHE, cache, Cache, da, DA, Da] - Original Data
[CACHE, cache, Cache, da, DA, Da] Primary
[CACHE, cache, Cache, da, DA, Da] Secondary
[cache, Cache, CACHE, da, Da, DA] Tertiary

但我真正期待的结果是:

[abc, àbc, äbc, Abc, ABC, Àbc, Äbc] Tertiary
[cache, da, Cache, CACHE, Da, DA] Tertiary

换句话说,我希望所有小写首先(按字母顺序排序),然后是大写(反之亦然)。这不是一个合理的期望吗?

4 个答案:

答案 0 :(得分:3)

有趣的是,android javadoc比oracle更有帮助 - 特别是:

  

当字符串中的任何位置存在主要或次要差异时,将忽略第三个差异。

另外值得注意的是:您获得的顺序是您在法语区域设置中所期望的。根据{{​​3}}:

  

Enpremièrealalysis,lescaractèresaccentués,demêmequeles majuscules,ontlemêmeranngalbétiquequelecaractèrefondamental。
  Si plusieurs mots ontlemêmeranngalbétique,ontâchedelesistingure entreeuxgrâceauxmajuscules et aux accents(pour le e,on l'ordre e,é,è,ê,ë)

英文(我的斜体加法):

  

第一步是对字母进行排名,不论其重音或大小写(即:a,A,à等级相同)。如果在第一步之后有几个单词具有相同的等级,则会考虑大小写和重点。

换句话说,c(小上限)和D(大上限)将始终可以按主要强度进行排序,而第三强度不会改变该顺序。

因此,在您的示例中,无论案例和重音如何,您在cache之前始终都会da。如果主要字母相同(c(小)与C(大),则情况只会有所不同。

答案 1 :(得分:1)

示例代码按预期工作。您可以使用自定义归类规则来获得所需的输出。

RuleBasedCollator是JDK中Collat​​or的唯一子类。您对Collat​​or.getInstance(Locale.FRANCE)的调用返回RuleBasedCollat​​or的实例

您可以使用

创建自己的实例
RuleBasedCollator myCollator = new RuleBasedCollator(rules);

规则的格式在javadoc中给出。

希望它有所帮助。

答案 2 :(得分:1)

另一种选择:如果您需要自定义区域设置的规则,可以尝试使用RuleBasedCollat​​or:

check: FuncMap_1.1.2.tar.gz

答案 3 :(得分:0)

您不应该对区域设置敏感的整理器的结果排序做出假设。

这并不是要反映像ASCII顺序这样的技术方面,而是反映人类语言规则,例如:因为人们会在图书馆中分类书籍或在电话簿中分类。通常情况下,您将找不到带有小写字母的大写书架的书架。

为了说明更令人惊讶的行为,请查看以下示例:

String s1="IDONTCARE", s2="idontcare";
System.out.println("Comparing '"+s1+"' and '"+s2+"' locale sensitive");
Locale[] all={ Locale.ENGLISH, new Locale("tr") };
for(Locale l:all)
{
  System.out.println();
  System.out.println(l);
  Collator c1=Collator.getInstance(l);
  c1.setStrength(Collator.PRIMARY);
  System.out.println("primary:\t"+c1.compare(s1, s2));
  c1.setStrength(Collator.SECONDARY);
  System.out.println("secondary:\t"+c1.compare(s1, s2));
  c1.setStrength(Collator.TERTIARY);
  System.out.println("tertiary:\t"+c1.compare(s1, s2));
  c1.setStrength(Collator.IDENTICAL);
  System.out.println("identical:\t"+c1.compare(s1, s2));
}

它将打印:

Comparing 'IDONTCARE' and 'idontcare' locale sensitive

en
primary:    0
secondary:  0
tertiary:   1
identical:  1

tr
primary:    -1
secondary:  -1
tertiary:   -1
identical:  -1

如上所述,不要指望知道结果并忘记与合作者的ASCII / Unicode词典顺序。