11

引自 Joshua Bloch 的 Effective Java - Second Edition

对于浮点字段,使用 Double.compare 或 Float.compare 代替关系运算符,它们在应用于浮点值时不遵守compareTo的一般约定。

它没有详细说明为什么会这样。

所以,我的问题是:

当与浮点值一起使用时,关系运算符以何种方式不遵守 compareTo 的一般约定?

4

3 回答 3

6

javadoc

 public int compareTo(Double anotherDouble)

以数字方式比较两个 Double 对象。当应用于原始双精度值时,此方法执行的比较与 Java 语言数值比较运算符(<、<=、==、>=、>)执行的比较有两种不同之处:此方法考虑 Double.NaN方法等于自身并且大于所有其他双精度值(包括 Double.POSITIVE_INFINITY)。此方法认为 0.0d 大于 -0.0d。这确保了此方法强加的 Double 对象的自然排序与 equals 一致。

于 2012-10-12T20:54:52.887 回答
4

来自 JavaDocDouble::compareTo

以数字方式比较两个 Double 对象。当应用于原始双精度值时,此方法执行的比较与 Java 语言数值比较运算符(<、<=、==、>= >)执行的比较有两种不同之处:

  • 此方法认为 Double.NaN 等于其自身并且大于所有其他双精度值(包括 Double.POSITIVE_INFINITY)。

  • 此方法认为 0.0d 大于 -0.0d。

这确保了 Double.compareTo(Object)(将其行为转发给此方法)遵守 Comparable.compareTo 的一般约定,并且 Doubles 上的自然顺序与 equals 一致。

    double d1 =Double.NaN;
    double d2 = Double.NaN;

    System.out.println(Double.valueOf(d1).equals(d2));    ---> true
    System.out.println(Double.valueOf(d1).compareTo(d2));  ---> 0
    System.out.println(d1 == d2);                          --->false
于 2012-10-12T20:54:39.910 回答
1

根据 [Joshua_Bloch] Effective_Java,第 3 版

本书的先前版本(第 2 版)建议 compareTo 方法使用关系运算符 < 和 > 比较整数原始字段,使用静态方法 Double.compare 和 Float.compare 比较浮点原始字段。在 Java 7 中,静态比较方法被添加到 Java 的所有盒装原始类中。在 compareTo 方法中使用关系运算符 < 和 > 很冗长且容易出错,因此不再推荐。

在 compareTo 方法的实现中比较字段值时,避免使用 < 和 > 运算符。相反,使用盒装原始类中的静态比较方法或 Comparator 接口中的比较器构造方法。

于 2019-01-08T09:38:11.997 回答