我读到这些方法的返回值的规则是对于obj1.compareTo(obj2),例如,如果obj2在层次结构中的obj1下,则返回值为负数,如果它位于obj1之上,然后它是正面(如果它相等,那么它就是0)。但是,在我的班级中,我看到了使用Math.signum的示例,以便在compareTo方法中获得-1(对于负数)和1(对于正数)。
有什么理由吗?
编辑:
这是我的意思:
Comparator comp = new Comparator() {
public int compare(Object obj1, Object obj2) {
Book book1 = (Book) obj1;
Book book2 = (Book) obj2;
int order = book1.getAuthor().compareTo(book2.getAuthor());
if (order == 0) {
order = (int) Math.signum(book1.getPrice() - book2.getPrice());
}
return order;
};
答案 0 :(得分:3)
是否有任何理由使用 Math.signum
是有。
order = (int) Math.signum(book1.getPrice() - book2.getPrice());
假设您已使用此
替换上述行order = (int)(book1.getPrice() - book2.getPrice());
现在让我们假设
book1.getPrice() returns 10.50
book2.getPrice() returns 10.40
如果您不使用 signum ,您将永远不会有任何编译时间或运行时错误,但订单的值将为0.这意味着book1等于book2这在逻辑上是错误的。
但如果您使用 signum 订单的值将为1,这意味着book1>第二册。
但必须提到的是,你永远不应该对比较函数返回1到-1之间的值做任何假设。 您可以阅读比较器http://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html的官方文件。
答案 1 :(得分:1)
任何负数都可以表明<湾任何正数都会显示>湾-1和1服务于此目的就好了。没有"没有"更没有"或者"更大于&#34 ;;它们是二元属性。允许任何负(或正)值的原因可能是历史的;对于整数,通过简单的减法来实现比较器很常见。
答案 2 :(得分:1)
没有
PS :实施中经常出现的错误是使用减法
public int compareTo(Object o) {
OurClass other = (OurClass)o; //Skip type check
return this.intField - other.intField;
}
这是错误的,因为如果你打电话给new OurClass(Integer.MIN_VALUE).compareTo(new OurClass(Integer.MAX_VALUE))
就会出现溢出。可能Math.abs
尝试(失败)来处理这个问题。
答案 3 :(得分:0)
我能看到的唯一原因是,如果你想比较两个int
例如(a
和b
),那么你就写了
return a - b;
它可能会溢出。如果你将它们转换为双打并使用(int)Math.signum( (double)a - (double)b )
,你肯定会避免这种情况。但是有更简单的方法可以实现相同的效果,例如Integer.compare( a, b)
。