Java:了解 Comparator 的工作原理(返回 -1 和 0 )
Java: Understand how Comparator works (returning -1 and 0 )
这是代码
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;
}
}
这是问题陈述
您有一组日志。每个日志都是 space 分隔的字符串。
对于每个日志,每个日志中的第一个词是字母数字标识符。然后,要么:
Each word after the identifier will consist only of lowercase letters, or;
Each word after the identifier will consist only of digits.
我们将这两种日志称为字母日志和数字日志。保证每条日志在标识后至少有一个词。
重新排序日志,使所有字母日志都排在任何数字日志之前。字母日志按字典顺序排列,忽略标识符,在连接的情况下使用标识符。数字日志应按其原始顺序放置。
Return日志的最终顺序。
示例 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 会做同样的事情。那么,实际的区别是什么?谢谢
虽然 Comparable<T>
的 int compareTo(T o)
方法将 this
与指定的对象进行比较,但 Comparator<T>
的 int compare(T o1, T o2)
比较同一类型的两个不同实例.这两种方法都有相同的数学契约。正如 Joshua Bloch 在 Effective Java 中提到的:
Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object. Throws ClassCastException
if the specified object’s type prevents it from being compared to this object.
In the following description, the notation sgn(expression)
designates the mathematical signum
function, which is defined to return -1, 0, or 1, according to whether the value of expression is negative, zero, or positive.
• The implementor must ensure that sgn(x.compareTo(y)) == -sgn(y.compareTo(x))
for all x and y. (This implies that x.compareTo(y)
must throw an exception if and only if y.compareTo(x)
throws an exception.)
• The implementor must also ensure that the relation is transitive: (x.compareTo(y) > 0 && y.compareTo(z) > 0)
implies x.compareTo(z) > 0
.
• Finally, the implementor must ensure that x.compareTo(y) == 0
implies that
sgn(x.compareTo(z)) == sgn(y.compareTo(z))
, for all z.
• It is strongly recommended, but not required, that (x.compareTo(y) == 0) == (x.equals(y))
. Generally speaking, any class that implements the Comparable interface and violates this condition should clearly indicate this fact.
对于Comparator
、Comparable
等...,传递了两个参数。如果第二个参数较大,则 return 任何负数;如果它们相等,则为 0;如果第一个参数较大,则为正数。对于负数和正数,它不必是 -1 或 1。例如,如果您要比较哪个数字较大,compare(5, 10)
会 return 为负数,例如 -1,因为 10 大于 5。
这是代码
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;
}
}
这是问题陈述
您有一组日志。每个日志都是 space 分隔的字符串。
对于每个日志,每个日志中的第一个词是字母数字标识符。然后,要么:
Each word after the identifier will consist only of lowercase letters, or;
Each word after the identifier will consist only of digits.
我们将这两种日志称为字母日志和数字日志。保证每条日志在标识后至少有一个词。
重新排序日志,使所有字母日志都排在任何数字日志之前。字母日志按字典顺序排列,忽略标识符,在连接的情况下使用标识符。数字日志应按其原始顺序放置。
Return日志的最终顺序。
示例 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 会做同样的事情。那么,实际的区别是什么?谢谢
虽然 Comparable<T>
的 int compareTo(T o)
方法将 this
与指定的对象进行比较,但 Comparator<T>
的 int compare(T o1, T o2)
比较同一类型的两个不同实例.这两种方法都有相同的数学契约。正如 Joshua Bloch 在 Effective Java 中提到的:
Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object. Throws
ClassCastException
if the specified object’s type prevents it from being compared to this object.In the following description, the notation
sgn(expression)
designates the mathematicalsignum
function, which is defined to return -1, 0, or 1, according to whether the value of expression is negative, zero, or positive.• The implementor must ensure that
sgn(x.compareTo(y)) == -sgn(y.compareTo(x))
for all x and y. (This implies thatx.compareTo(y)
must throw an exception if and only ify.compareTo(x)
throws an exception.)• The implementor must also ensure that the relation is transitive:
(x.compareTo(y) > 0 && y.compareTo(z) > 0)
impliesx.compareTo(z) > 0
.• Finally, the implementor must ensure that
x.compareTo(y) == 0
implies thatsgn(x.compareTo(z)) == sgn(y.compareTo(z))
, for all z.• It is strongly recommended, but not required, that
(x.compareTo(y) == 0) == (x.equals(y))
. Generally speaking, any class that implements the Comparable interface and violates this condition should clearly indicate this fact.
对于Comparator
、Comparable
等...,传递了两个参数。如果第二个参数较大,则 return 任何负数;如果它们相等,则为 0;如果第一个参数较大,则为正数。对于负数和正数,它不必是 -1 或 1。例如,如果您要比较哪个数字较大,compare(5, 10)
会 return 为负数,例如 -1,因为 10 大于 5。