我們都知道使用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設置爲丹麥的結果是正確的。在這種情況下,它會產生錯誤。我當然明白爲什麼這個事情發生了:這僅僅是因爲該方法是相等這樣實現的:
return compare(s1, s2) == Collator.Equal;
這個方法調用,用於分類和檢查,如果字符串是相同的一個。它們不是,因爲丹麥特定的整理規則要求之後進行排序(如果我正確理解比較方法的結果)ae。然而,這些字符串是真的是相同,與此強度兩種情況下的差異和這種兼容性字符(這就是所謂的)應被視爲平等。
要解決這個問題,可以使用RuleBasedCollator以及適用於相等情況的特定規則集。
最後的問題是:CLDRchart似乎沒有人知道在哪裏可以得到這樣的特定規則(不僅是丹麥,但對其他語言),使兼容字符,連字等將作爲平等的(處理不包含這樣或我沒有搜索它)?
或者,也許我想在這裏做一些愚蠢的事,我真的應該使用簡單UCA是否相等的比較(任意代碼示例,請)?
字符串equals()完全按照它應該做的事情進行,並且在某些語言中將單詞與等效拼寫進行比較不是其中的一部分,所以我發現它的失敗是令人誤解的。 – Stefan
@Stefan:問題在於它不是。例如,對於包含重音字符或元音變音的字符串(à或ä),如果其中一個字符串使用規範分解,它將返回** false **。拼寫可能是一樣的,沒關係。更糟的結果會給你equalsIgnoreCase() - 例如sharp s或final sigma等案例變體將無法識別。這是因爲這些方法使用不適合國際字符串的二進制比較。 –
該關鍵字是規範分解。這是一種(自然)語言功能,與String represantation無關,實際上在大多數情況下,您希望將它們作爲字符串進行區別對待。我同意你在equalsIgnoreCase中的一個不好的地方,因爲它模糊了字符串和語言/語言環境中字符的容器之間的界限。 – Stefan