为什么要将同一个字符分别转换为大写和小写后进行比较?

6
以下代码在Java的String类中。我不明白为什么来自两个不同字符串的字符要进行两次比较,首先通过大写字母,如果失败则通过小写字母比较。
我的问题是,这是必需的吗?如果是,为什么?
  public static final Comparator<String> CASE_INSENSITIVE_ORDER
                                             = new CaseInsensitiveComparator();
        private static class CaseInsensitiveComparator
                implements Comparator<String>, java.io.Serializable {
            // use serialVersionUID from JDK 1.2.2 for interoperability
            private static final long serialVersionUID = 8575799808933029326L;

            public int compare(String s1, String s2) {
                int n1 = s1.length();
                int n2 = s2.length();
                int min = Math.min(n1, n2);
                for (int i = 0; i < min; i++) {
                    char c1 = s1.charAt(i);
                    char c2 = s2.charAt(i);
                    if (c1 != c2) {
                        c1 = Character.toUpperCase(c1);
                        c2 = Character.toUpperCase(c2);
                        if (c1 != c2) {
                            c1 = Character.toLowerCase(c1);
                            c2 = Character.toLowerCase(c2);
                            if (c1 != c2) {
                                // No overflow because of numeric promotion
                                return c1 - c2;
                            }
                        }
                    }
                }
                return n1 - n2;
            }
        }
1个回答

14
问题可能更为复杂。
有些字符在同一大写或小写形式中具有多个小写码点,反之亦然。因此,要检查大小写不敏感匹配,如果其中一个匹配,则需要比较大小写版本。
一个例子是希腊大写字母“Σ”有两种不同的小写形式:“ς”位于单词末尾,“σ”位于其他位置。 来源: 维基百科 对于大写不相等但小写非常相等的情况,VGR提供了这个很好的例子:
一个更好的例子是'\u0130' (İ) 和'I' 。通过 toUpperCase 传递它们将使它们保持不变(因此不同),但是通过 toLowerCase 传递将导致相同的字符值。

你能举个例子吗?字符串和字符不涉及字符集;字符集只用于将它们编码为字节。 - Erwin Bolwidt
来自维基百科:“希腊大写字母“Σ”有两种不同的小写形式:单词末尾为“ς”,其他位置为“σ”。https://en.wikipedia.org/wiki/Letter_case - Jan
toUpperCase 不关心字符串中字符的位置。 - samczsun
1
@Jan 或许你可以说“有些字母存在多个小写字符对应同一个大写字符”的情况,或者更精确地说,“有些字母存在多个小写码点对应同一个大写码点”的情况。 - Erwin Bolwidt
1
一个更好的例子是 '\u0130' (İ) 和 'I'。将它们传递给 toUpperCase 不会改变它们(因此它们不同),但将它们传递给 toLowerCase 会得到相同的字符值。 - VGR
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接