Java: понять, как работает Comparator (возвращая -1 и 0) - PullRequest
0 голосов
/ 23 марта 2020

Вот код

class Solution {
    public String[] reorderLogFiles(String[] logs) {
        Arrays.sort(logs, (s1, s2) -> {
            String[] split1 = s1.split(" ", 2);
            String[] split2 = s2.split(" ", 2);

            boolean isDigit1 = Character.isDigit(split1[1].charAt(0));
            boolean isDigit2 = Character.isDigit(split2[1].charAt(0));

            if(!isDigit1 && !isDigit2) {
                // both letter-logs. 
                int comp = split1[1].compareTo(split2[1]);
                if (comp == 0) return split1[0].compareTo(split2[0]);
                else return comp;
            } else if (isDigit1 && isDigit2) {
                // both digit-logs. So keep them in original order
                return 0; 
            } else if (isDigit1 && !isDigit2) {
                // first is digit, second is letter. bring letter to forward.
                return 1;
            } else {
                //first is letter, second is digit. keep them in this order.
                return -1; 
            }
        });
        return logs;
    }
}

Это постановка задачи

У вас есть массив журналов. Каждый журнал представляет собой строку слов, разделенную пробелом.

Для каждого журнала первое слово в каждом журнале представляет собой алфавитный идентификатор c. Затем либо:

Each word after the identifier will consist only of lowercase letters, or;
Each word after the identifier will consist only of digits.

Мы назовем эти две разновидности журналов буквами-логами и ди git -логами. Гарантируется, что в каждом журнале есть хотя бы одно слово после идентификатора.

Переупорядочьте журналы так, чтобы все журналы писем предшествовали любому журналу di git. Буквенные журналы упорядочены лексикографически, игнорируя идентификатор, с идентификатором, используемым в случае связей. Di git -логи должны быть помещены в их первоначальном порядке.

Возвращает окончательный порядок журналов.

Пример 1:

Input: logs = ["dig1 8 1 5 1","let1 art can","dig2 3 6","let2 own kit dig","let3 art zero"]
Output: ["let1 art can","let3 art zero","let2 own kit dig","dig1 8 1 5 1","dig2 3 6"]

Мой запрос

Я не понимаю, что разница между возвратом 0 и возвратом -1

То, что я считал -1, не меняет первоначальный порядок двух объектов при сравнении, но возвращение 0 делает то же самое. Так в чем же разница? Спасибо

Ответы [ 2 ]

0 голосов
/ 23 марта 2020

Для Comparator, Comparable, et c ... передано два аргумента. Вы возвращаете любое отрицательное число, если второй аргумент больше, 0, если они равны, и положительное число, если первый аргумент больше. Это не должно быть -1 или 1 для отрицательных и положительных чисел. Например, если вы сравниваете, какое число больше, compare(5, 10) вернет что-то отрицательное, например, -1, потому что 10 больше 5.

0 голосов
/ 23 марта 2020

Хотя метод Comparable<T> int compareTo(T o) сравнивает this с указанным объектом, Comparator<T> int compare(T o1, T o2) сравнивает два разных экземпляра одного типа. Оба метода имеют одинаковый математический контракт. Как упомянуто в Effective Java Джошуа Блохом:

Возвращает отрицательное целое число, ноль или положительное целое число, поскольку этот объект меньше, равен или больше указанного объекта. Выдает ClassCastException, если тип указанного объекта не позволяет сравнивать его с этим объектом.

В следующем описании обозначение sgn(expression) обозначает математическую функцию signum, которая определена для возврата -1, 0 или 1, в зависимости от того, является ли значение выражения отрицательным, нулевым или положительным.

• Разработчик должен убедиться, что sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) для всех x и y. (Это означает, что x.compareTo(y) должно выдавать исключение тогда и только тогда, когда y.compareTo(x) выдает исключение.)

• Разработчик также должен обеспечить транзитивность отношения: (x.compareTo(y) > 0 && y.compareTo(z) > 0) подразумевает x.compareTo(z) > 0.

• Наконец, разработчик должен убедиться, что x.compareTo(y) == 0 означает, что sgn(x.compareTo(z)) == sgn(y.compareTo(z)) для всех z.

• Настоятельно, но не обязательно, (x.compareTo(y) == 0) == (x.equals(y)). Вообще говоря, любой класс, который реализует интерфейс Comparable и нарушает это условие, должен четко указывать на этот факт.

...