我们都知道使用String的equals()方法进行相等比较会失败。相反,应该使用Collator,如下所示:
// we need to detect User Interface locale somehow
Locale uiLocale = Locale.forLanguageTag("da-DK");
// Setting up collator object
Collator collator = Collator.getInstance(uiLocale);
collator.setStrength(Collator.SECONDARY);
collator.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
// strings for equality testing
String test1 = "USA lover Grækenland støtte";
String test2 = "USA lover graekenland støtte";
boolean result = collator.equals(test1, test2);
现在,此代码有效,结果为真 ,除非 uiLocale设置为丹麦语。在这种情况下,它会产生错误。我当然理解 为什么 这发生了:这只是因为方法equals是这样实现的:
return compare(s1, s2) == Collator.Equal;
此方法调用用于排序的方法并检查字符串是否相同。它们不是,因为丹麦特定的整理规则要求æ排序后(如果我正确理解比较方法的结果) ae 。但是,这些字符串真的相同,具有这种强度的情况差异和这样的兼容性字符(这就是它所谓的)应被视为相等。
要解决这个问题,可以使用RuleBasedCollator一套适用于相等案例的特定规则 最后问题是:有没有人知道我可以在哪里获得这样的特定规则(不仅对丹麦语而且对其他语言也是如此),以便兼容性字符,连字等被视为相等(CLDR {{ 3}}似乎没有包含这样或我搜索失败的那些)?
或许我想在这里做一些愚蠢的事情,我应该简单地使用chart进行相等比较(请问任何代码示例)?
答案 0 :(得分:3)
我找不到丹麦现有的Collator;丹麦语区域内置的应该是正确的。我不确定您ae
应该与æ
进行排序的假设,特别是由于丹麦语中的某些外来词(例如"aerofobi")(我不是丹麦语发言人,尽管我说瑞典语。)
但是,如果你想要将它们排序在一起,看起来你有两种方法可以做到这一点,具体取决于你所处的环境。在某些情况下,只更换字符可能是适当的:
String str = "USA lover graekenland støtte";
String sortStr = str.replace("ae", "æ");
另一个,或许更好的选择是你指定的那个;使用RuleBasedCollator
。使用javadocs中的示例,这非常简单:
String danish = "< a, A < b, B < c, C < d, D < e, E < f, F < g, G < h, H < i, I" +
"< j, J < k, K < l, L < m, M < n, N < o, O < p, P < q, Q < r, R" +
"< s, S < t, T < u, U < v, V < w, W < x, X < y, Y < z, Z" +
"< \u00E6 = ae," + // Latin letter ae
" \u00C6 = AE " + // Latin letter AE
"< \u00F8, \u00D8" + // Latin letter o & O with stroke
"< \u00E5 = a\u030A," + // Latin letter a with ring above
" \u00C5 = A\u030A;" + // Latin letter A with ring above
" aa, AA";
RuleBasedCollator danishCollator = new RuleBasedCollator(danish);
然后您可以使用:
String test1 = "USA lover Grækenland støtte";
String test2 = "USA lover Graekenland støtte"; // note capital 'G'
boolean result = danishCollator.equals(test1, test2); // true
如果您认为默认展开器不正确,您可能希望report a bug。 (之前有similar bugs)。
更新:我使用印刷的丹麦语百科全书检查了这一点。确实有一个单词以'ae'开头(主要是来自外语的单词;例如“有氧运动”),这些单词不与'æ'开头的单词排序(因此不等于)。因此,虽然我知道为什么你想在许多情况下将它们视为平等,但它们并非严格如此。
答案 1 :(得分:0)
获取特定区域设置规则的一种方法是使用getRules函数。但是,在Android中,此函数返回一个空字符串。
if (collTemp.compare(target, str) < 0)
这些规则与比较功能使用的规则相同。
@Override
public boolean isCellEditable(int i, int y) {
return true;
}
注意:我尝试将规则从我的JDK桌面应用程序字符串插入Android RuleBasedCollator构造函数,但我得到了U_INVALID_FORMAT_ERROR(仅限Android)。所以我仍在试图弄清楚如何在Android中获得美国规则。