3 回答

TA貢獻(xiàn)1863條經(jīng)驗(yàn) 獲得超2個(gè)贊
創(chuàng)建您自己的RuleBasedCollator。
檢查返回的字符串的值
((RuleBasedCollator)Collator.getInstance(new Locale("sv", "SE"))).getRules()
并修改它以滿足您的需求,然后使用您修改的規(guī)則創(chuàng)建一個(gè)新的整理器。
并且可能也提交一份 JDK 錯(cuò)誤報(bào)告,這是一個(gè)很好的衡量標(biāo)準(zhǔn)。

TA貢獻(xiàn)1772條經(jīng)驗(yàn) 獲得超8個(gè)贊
這將 waaa 置于 vbbb 之前,將 vaaa 置于 wbbb 之前。顯然它將 v 和 w 視為同一個(gè)字母。
即使在瑞典語言環(huán)境中,JDK 也確實(shí)不會將 'w' 和 'v' 視為相同的字符。字母“v”出現(xiàn)在“w”之前。
Assert.assertEquals(1, stringComparator.compare("w", "v"));//TRUE
但是,根據(jù)瑞典的排序規(guī)則,JDK 將 'wa' 排序在 'vb' 之前。
Assert.assertEquals(1, stringComparator.compare("wa", "vb"));//FALSE

TA貢獻(xiàn)1802條經(jīng)驗(yàn) 獲得超5個(gè)贊
您可以創(chuàng)建一個(gè)自定義比較器,它包裝整理器并手動(dòng)處理v您w想要的方式。
我對此做了兩個(gè)實(shí)現(xiàn)。
第一個(gè)簡短而優(yōu)雅,它使用 Guavaslexicographical比較器以及 Holger 在評論中提供的棘手的正則表達(dá)式。
private static final Pattern VW_BOUNDARY = Pattern.compile("(?=[vw])|(?<=[vw])", Pattern.CASE_INSENSITIVE);
public static Comparator<String> smallCorrectVwWrapper(Comparator<Object> original) {
return Comparator.comparing(
s -> Arrays.asList(VW_BOUNDARY.split((String) s)),
Comparators.lexicographical(original));
第二個(gè)實(shí)現(xiàn)是一個(gè)大而復(fù)雜的事情,它做同樣的事情,但是手動(dòng)實(shí)現(xiàn),沒有庫和正則表達(dá)式。
public static Comparator<String> correctVwWrapper(Comparator<Object> original) {
return (s1, s2) -> compareSplittedVw(original, s1, s2);
}
/**
* Compares the two string by first splitting them into segments separated by W
* and V, then comparing the segments one by one.
*/
private static int compareSplittedVw(Comparator<Object> original, String s1, String s2) {
List<String> l1 = splitVw(s1);
List<String> l2 = splitVw(s2);
int minSize = Math.min(l1.size(), l2.size());
for (int ix = 0; ix < minSize; ix++) {
int comp = original.compare(l1.get(ix), l2.get(ix));
if (comp != 0) {
return comp;
}
}
return Integer.compare(l1.size(), l2.size());
}
private static boolean isVw(int ch) {
return ch == 'V' || ch == 'v' || ch == 'W' || ch == 'w';
}
/**
* Splits the string into segments separated by V and W.
*/
public static List<String> splitVw(String s) {
var b = new StringBuilder();
var result = new ArrayList<String>();
for (int offset = 0; offset < s.length();) {
int ch = s.codePointAt(offset);
if (isVw(ch)) {
if (b.length() > 0) {
result.add(b.toString());
b.setLength(0);
}
result.add(Character.toString((char) ch));
} else {
b.appendCodePoint(ch);
}
offset += Character.charCount(ch);
}
if (b.length() > 0) {
result.add(b.toString());
}
return result;
}
用法:
public static void main(String[] args) throws Exception {
Comparator<String> stringComparator = correctVwWrapper(Collator.getInstance(new Locale("sv", "SE")));
System.out.println(stringComparator.compare("a", "z") < 0); // true
System.out.println(stringComparator.compare("wa", "vz") < 0); // false
System.out.println(stringComparator.compare("wwa", "vvz") < 0); // false
System.out.println(stringComparator.compare("va", "wz") < 0); // true
System.out.println(stringComparator.compare("v", "w") < 0); // true
}
實(shí)現(xiàn)一個(gè) wrapping 需要做更多的工作Collator,但它不應(yīng)該太復(fù)雜。
添加回答
舉報(bào)