Подтвердить что ты не робот

Интересует внедрение CaseInsensitiveComparator

Пока я проверяю реализацию CaseInsensitiveComparator, который является частным внутренним классом String, я обнаружил странную вещь.

private static class CaseInsensitiveComparator
        implements Comparator<String>, java.io.Serializable {
    ...
    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;
    }
    ...
}

Мне любопытно следующее: в цикле for, как только вы сравниваете верхние символы с обложкой, почему вы должны снова сравнить нижние символы обложки? Когда Character.toUpperCase(c1) и Character.toUpperCase(c2) различны, возможно ли, что Character.toLowerCase(c1) и Character.toLowerCase(c2) равны?

Не удалось ли это упростить?

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) {
                // No overflow because of numeric promotion
                return c1 - c2;
            }
        }
    }
    return n1 - n2;
}

Я что-то пропустил?

4b9b3361

Ответ 1

Существуют символы Unicode, которые отличаются в нижнем регистре, но имеют одинаковую форму в верхнем регистре. Например, греческая буква Sigma - имеет две строчные формы (σ и ς, которые используются только в конце слова), но только одна форма в верхнем регистре (Σ).

Я не мог найти никаких примеров обратного, но если такая ситуация произошла в будущем, текущая реализация Java уже подготовлена ​​для этого. Ваша версия Comparator будет корректно обрабатывать регистр Sigma.

Дополнительную информацию можно найти в Часто задаваемые вопросы по сопоставлению с картой на веб-сайте Юникода.