有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在哪里可以找到字符串相等比较的一组特定排序规则?

我们都知道,使用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设置为丹麦语。在这种情况下,它将产生false。我当然理解发生这种情况的原因:这只是因为方法equals是这样实现的:

return compare(s1, s2) == Collator.Equal;

此方法调用用于排序和检查字符串是否相同的方法。它们不是,因为丹麦特定的排序规则要求æae之后排序(如果我正确理解比较方法的结果)。但是,这些字符串实际上是相同的,有了这个强度,大小写差异和兼容字符(这就是它的名称)应该被视为相等的

要解决这个问题,可以将RuleBasedCollator与一组特定的规则一起使用,这些规则将适用于平等情况
最后一个问题是:是否有人知道我可以从哪里获得这样的特定规则(不仅针对丹麦语,还针对其他语言),以便兼容字符、连字等被视为相等(CLDRchart似乎不包含这样的规则,或者我搜索失败)

或者我想在这里做一些愚蠢的事情,我真的应该简单地使用UCA进行等式比较(请选择任何代码示例)


共 (2) 个答案

  1. # 1 楼答案

    获取特定区域设置的规则的一种方法是使用getRules函数。但是,在Android中,此函数返回一个空字符串

        RuleBasedCollator collTemp = (RuleBasedCollator) Collator
                .getInstance(Locale.US);
        String usRules = collTemp.getRules();
    
    
        //Save rules in a file
        String rulesPath = "C:\\projects\\droid\\rules.txt";
        BufferedWriter out = new BufferedWriter
                (new OutputStreamWriter(new FileOutputStream(rulesPath),"UTF-16"));
        out.write(usRules);
        out.close();
    

    这些规则与比较函数使用的规则相同

    if (collTemp.compare(target, str) < 0)
    

    注意:我试图将JDK桌面应用程序字符串中的规则插入到Android RuleBasedCalator构造函数中,但我得到了U_无效_格式_错误(仅在Android中)。因此,我仍在试图找出如何在安卓系统中获得美国规则

  2. # 2 楼答案

    我找不到任何现有的丹麦语拼贴画;丹麦地区的内置版本应该是正确的。我不确定您是否认为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
    

    如果您认为默认的collator不正确,您可能希望report a bug。(以前有similar bugs

    更新:我用一本印刷的丹麦语百科全书对此进行了检查。确实有以“ae”开头的单词(主要是来自外语的单词;“健美操”,例如)与以“æ”开头的单词排序(因此不等于)。所以,尽管我明白为什么在很多情况下,你们会希望把他们平等对待,但严格来说,他们并不是这样