【问题标题】:Java: Understand how Comparator works (returning -1 and 0 )Java:了解 Comparator 的工作原理(返回 -1 和 0 )
【发布时间】:2020-03-23 18:34:38
【问题描述】:

这里是代码

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;
    }
}

这是问题陈述

您有一组日志。每个日志都是一个以空格分隔的字符串。

对于每个日志,每个日志中的第一个单词是一个字母数字标识符。然后,要么:

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

我们将这两种日志称为字母日志和数字日志。保证每条日志的标识符后至少有一个单词。

重新排序日志,使所有字母日志都排在任何数字日志之前。字母日志按字典顺序排序,忽略标识符,标识符用于平局。数字日志应按其原始顺序放置。

返回日志的最终顺序。

示例 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 会做同样的事情。那么,实际的区别是什么?谢谢

【问题讨论】:

  • 0 表示顺序相等,-1 表示第一个参数在第二个参数之前
  • 但是第一个参数不是已经在第二个参数之前了吗?
  • 零并不一定“保持原样”顺便说一句。这完全取决于stability of the sort。你很幸运,底层算法是 - 我相信 - timsort,它是稳定的。从技术上讲,这是一个实现细节,可能会在未来的版本中发生变化。
  • 不明白你的意思。就像我说的,0 和 -1 之间存在差异,在等于和小于之间。 “-1 在比较时不会改变两个对象的原始顺序” 确实如此。它将第一个参数放在第二个之前。

标签: java compare comparator comparable


【解决方案1】:

虽然Comparable<T>int compareTo(T o) 方法将this 与指定的对象进行比较,但Comparator<T>int compare(T o1, T o2) 比较相同类型的两个不同实例。两种方法具有相同的数学契约。正如 Joshua Bloch 在 Effective Java 中提到的:

返回负整数、零或正整数,因为此对象小于、等于或大于指定对象。如果指定对象的类型阻止它与此对象进行比较,则抛出 ClassCastException

在以下描述中,符号sgn(expression) 表示数学signum 函数,该函数定义为根据表达式的值是负数、零还是正数返回-1、0 或1。

• 实现者必须确保sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) 用于所有x 和y。 (这意味着当且仅当y.compareTo(x) 抛出异常时,x.compareTo(y) 必须抛出异常。)

• 实现者还必须确保关系是可传递的:(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 接口并违反此条件的类都应该清楚地表明这一事实。

【讨论】:

    【解决方案2】:

    对于Comparator's、Comparable 等...,传递了两个参数。如果第二个参数较大,则返回任何负数,如果相等则返回 0,如果第一个参数较大,则返回正数。对于负数和正数,它不必是 -1 或 1。例如,如果您要比较哪个数字更大,compare(5, 10) 将返回负数,例如 -1,因为 10 大于 5。

    【讨论】:

    • Comparable 只有一个参数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-20
    • 2012-12-11
    • 2011-02-18
    • 2018-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多