8

我试图了解区分大小写的顺序应该如何使用Java Collat​​or真正起作用。

此示例中,以下字符串在法语语言环境中使用所有优势进行排序(出于说明目的,我在数据集中添加了一些额外的字符串):

[Ä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

4 回答 4

4

有趣的是,android javadoc比 oracle 更有用——特别是:

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

另外值得注意的是:您获得的顺序是您在法语语言环境中所期望的。根据关于“orderre alphabétique”的维基百科文章

En première analysis, les caractères accentués, de meme que les majuscules, ont le meme rang alphabétique que le caractère fundamental。
Si plusieurs mots ont le même rang alphabétique, on tâche de les distinguer entre eux grâce aux majuscules et aux 口音(pour le e, on a l'ordre e, é, è, ê, ë)

英文(我的斜体字):

第一步包括对字母进行排序,无论它们的重音或大小写如何(即:a,A,à 排名相同)。如果在第一步之后多个单词具有相同的排名,则将考虑大小写和重读。

换句话说,c(small cap) 和D(large cap) 将始终可以按主要强度排序,而第三强度不会改变该顺序。

因此,在您的示例中,无论大小写和重音如何,您都将始终拥有cachebefore 。仅当主字母相同(例如(小)与(大))时,da大小写才会有所不同。cC

于 2013-09-16T12:27:51.890 回答
1

The sample code is working as intended. You can use custom collation rules to get the desired output.

RuleBasedCollator is the only subclass of Collator in JDK. Your call to Collator.getInstance(Locale.FRANCE) returns an instance of RuleBasedCollator

You could create your own instance using

RuleBasedCollator myCollator = new RuleBasedCollator(rules);

The format for rules is given in the javadoc.

Hope it helps.

于 2013-09-18T06:10:55.937 回答
1

另一种选择:如果您需要自定义语言环境的规则,可以尝试使用 RuleBasedCollat​​or:

    RuleBasedCollator collTemp = (RuleBasedCollator) Collator.getInstance(Locale.US);

    String usRules = collTemp.getRules();

    //Remove dashes rule from US locale (dashes come after letters)
    usRules = usRules.replace(",'-'", "");

    //Create a collator with customized rules    
    RuleBasedCollator coll = new RuleBasedCollator(usRules);

    //Sort the collection based on collator
    Collections.sort(lines, coll);
于 2015-07-13T18:34:02.793 回答
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 字典顺序。

于 2013-09-18T16:37:25.707 回答