简单 == 而不是 doubleToLongBits
simple == instead of doubleToLongBits
我有两个双精度值(原始类型和非对象!),当我让 Eclipse 为这些双精度值生成 equals/hashCode
时,它会覆盖它那:
@Override
public boolean equals(Object obj) {
...
return Double.doubleToLongBits(mydouble) == Double.doubleToLongBits(obj.mydouble) && ..;
}
所以它使用doubleToLongBits
来比较是否相等。但是,当使用 doubleToLongBits
时,0!=-0
returns 的比较是错误的。为什么在 equals
方法中需要这个?
我的问题:为什么 Eclipse 不简单地使用
@Override
public boolean equals(Object obj) {
..
return mydouble == obj.mydouble && ..;
}
比较是否相等?这会是错误的吗?
问题是针对原始类型的,以及为什么人们应该 doubleToLongBits
使用原始类型而不是简单地使用,例如0.1 == 0.1
.
它是这样做的,因为它遵循 Double.compare() 实现 - 所以它与 Java 默认提供的一致:
public static int compare(double d1, double d2) { //Java 12 implementation
if (d1 < d2)
return -1; // Neither val is NaN, thisVal is smaller
if (d1 > d2)
return 1; // Neither val is NaN, thisVal is larger
// Cannot use doubleToRawLongBits because of possibility of NaNs.
long thisBits = Double.doubleToLongBits(d1);
long anotherBits = Double.doubleToLongBits(d2);
return (thisBits == anotherBits ? 0 : // Values are equal
(thisBits < anotherBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
1)); // (0.0, -0.0) or (NaN, !NaN)
}
编辑:也等于 class
public boolean equals(Object obj) {
return (obj instanceof Double)
&& (doubleToLongBits(((Double)obj).value) ==
doubleToLongBits(value));
}
要回答"Why does Eclipse use doubleToLongBits"?
这是代码生成功能。 Eclipse 不知道上下文。它只是试图咕哝出一些基本上没问题的东西。如果它生成类似 this.d == that.d
的东西,它将触发各种静态分析工具,这些工具会将行标记为比较两个双精度数(因为它们有像 this one 这样的规则)。相反,它比较 long 并且静态分析工具很高兴,因为它们很愚蠢(对很多事情很有用,但很容易被愚弄)。
如果您使用的是双精度数,那么在一定范围内区分两个值是没有用的。在这方面,这些替代方案中的任何一种都比另一种更能帮助您。这只是静态分析工具触发次数多于其他一次的原因。
通常,当您创建一个 equals 方法时,它是针对某个域对象的。 equals 和 hashcode 方法不一定考虑对象上的所有字段,很多时候它们使用称为业务键的子集,该子集唯一标识对象。可能在这里您根本不需要在 equals 或 hashCode 方法中包含此字段。同样,代码生成器没有上下文可以继续,并且将提供一种方法来包含所有字段,无论它是否有意义。
我有两个双精度值(原始类型和非对象!),当我让 Eclipse 为这些双精度值生成 equals/hashCode
时,它会覆盖它那:
@Override
public boolean equals(Object obj) {
...
return Double.doubleToLongBits(mydouble) == Double.doubleToLongBits(obj.mydouble) && ..;
}
所以它使用doubleToLongBits
来比较是否相等。但是,当使用 doubleToLongBits
时,0!=-0
returns 的比较是错误的。为什么在 equals
方法中需要这个?
我的问题:为什么 Eclipse 不简单地使用
@Override
public boolean equals(Object obj) {
..
return mydouble == obj.mydouble && ..;
}
比较是否相等?这会是错误的吗?
问题是针对原始类型的,以及为什么人们应该 doubleToLongBits
使用原始类型而不是简单地使用,例如0.1 == 0.1
.
它是这样做的,因为它遵循 Double.compare() 实现 - 所以它与 Java 默认提供的一致:
public static int compare(double d1, double d2) { //Java 12 implementation
if (d1 < d2)
return -1; // Neither val is NaN, thisVal is smaller
if (d1 > d2)
return 1; // Neither val is NaN, thisVal is larger
// Cannot use doubleToRawLongBits because of possibility of NaNs.
long thisBits = Double.doubleToLongBits(d1);
long anotherBits = Double.doubleToLongBits(d2);
return (thisBits == anotherBits ? 0 : // Values are equal
(thisBits < anotherBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
1)); // (0.0, -0.0) or (NaN, !NaN)
}
编辑:也等于 class
public boolean equals(Object obj) {
return (obj instanceof Double)
&& (doubleToLongBits(((Double)obj).value) ==
doubleToLongBits(value));
}
要回答"Why does Eclipse use doubleToLongBits"?
这是代码生成功能。 Eclipse 不知道上下文。它只是试图咕哝出一些基本上没问题的东西。如果它生成类似 this.d == that.d
的东西,它将触发各种静态分析工具,这些工具会将行标记为比较两个双精度数(因为它们有像 this one 这样的规则)。相反,它比较 long 并且静态分析工具很高兴,因为它们很愚蠢(对很多事情很有用,但很容易被愚弄)。
如果您使用的是双精度数,那么在一定范围内区分两个值是没有用的。在这方面,这些替代方案中的任何一种都比另一种更能帮助您。这只是静态分析工具触发次数多于其他一次的原因。
通常,当您创建一个 equals 方法时,它是针对某个域对象的。 equals 和 hashcode 方法不一定考虑对象上的所有字段,很多时候它们使用称为业务键的子集,该子集唯一标识对象。可能在这里您根本不需要在 equals 或 hashCode 方法中包含此字段。同样,代码生成器没有上下文可以继续,并且将提供一种方法来包含所有字段,无论它是否有意义。