我最近意识到,Java Collation似乎忽略了空格。
我列出了以下条款:
Amman Jost
Ammann Heinrich
Ammanner Josef
Bär Walter
Bare Werner
Barr Burt
Barraud Maurice
上面的订单反映了德国所需的订单,即占用空间。 但是,Java Collation使用
Collator collator = Collator.getInstance(Locale.GERMANY);
Collections.sort(values, collator);
给我以下顺序:
Amman Jost
Ammanner Josef
Ammann Heinrich
Bare Werner
Barraud Maurice
Barr Burt
Bär Walter
上面的结果实际上并不是我所期望的,因为不考虑空格(如下所述:Wikipedia Alphabetical order)。
这是否意味着,Java Collation不适用于此类用例,或者我在这里做错了什么?有没有办法让Java Collation空间知道?
我很乐意提出任何意见或建议。
答案 0 :(得分:9)
您可以自定义排序规则。尝试查看源代码,了解如何构建德语语言环境的Collator,如this answer中所述。
然后根据您的需求进行调整。 tutorial给出了一个起点。但是不需要做所有工作,其他人已经完成了它:看到这个blog post dealing with the exact same problem for Czech。
上面链接的解决方案的本质是:
String rules = ((RuleBasedCollator) Collator.getInstance(Locale.GERMANY)).getRules();
RuleBasedCollator correctedCollator
= new RuleBasedCollator(rules.replaceAll("<'\u005f'", "<' '<'\u005f'"));
这会在下划线规则之前为空格字符添加规则。
我承认我没有亲自测试过。
答案 1 :(得分:0)
如果由于某些原因无法修改语言环境,那么我建议您自己编写所有内容。这里有一些想法,虽然这段代码不完整但不起作用:
不要使用字符串列表,而是创建自己的对象,实现可比较的:
public class myString implements Comparable<myString> {
private String name;
public myString(String name) {
this.name = name;
}
}
然后您需要实施(参见示例here)
public int compareTo(myString compareMyString) {
...
}
现在变得比较棘手:
为了比较你的字符串,你需要拆分它们(这将产生一个字符串数组)。例如:
// Original String
"Barr Burt"
// Splitted String
[0]: "Barr"
[1]: "Burt"
您需要逐个比较单词。创建一个像这样的函数(这是一个伪代码:“this.words [i]”调用第一个单词“this.name”)
public int compareWords(myString compareMyString, int i)
{
if (this.words[i] < compareMyString.words[i])
return -1; // "this" should come before "compareMyString"
if (this.words[i] > compareMyString.words[i])
return 1; // "this" should come after "compareMyString"
if (this.words[i] == compareMyString.words[i])
return compareWords(i+1);
}
然后compareTo
:
public int compareTo(myString compareMyString) {
return compareWords(compareMyString, 0);
}