在 Java 中比较双打会产生奇怪的结果

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5230642/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 10:05:57  来源:igfitidea点击:

Comparing doubles in Java gives odd results

javadoubleequalsautoboxing

提问by Simeon

I really can'get my head around why the following happens:

我真的无法理解为什么会发生以下情况:

Double d = 0.0;
System.out.println(d == 0); // is true
System.out.println(d.equals(0)); // is false ?!

This however works as expected:

然而,这按预期工作:

Double d = 0.0;
System.out.println(d == 0.0); // true
System.out.println(d.equals(0.0)); // true

I'm positive that this is related to autoboxing in some way, but I really don't know why 0would be boxed differently when the ==operator is used and when .equalsis called.

我肯定这在某种程度上与自动装箱有关,但我真的不知道为什么0在使用==运算符和.equals调用时会以不同的方式装箱

Doesn't this implicitly violate the equalscontract ?

这不是暗中违反equals合同吗?

  *  It is reflexive: for any non-null reference value
  *     x, x.equals(x) should return
  *     true.

EDIT:

编辑

Thanks for the fast answers. I figured that it is boxed differently, the real question is: whyis it boxed differently ? I mean that this would be more intuitive if d == 0dthan d.equals(0d)is intuitive and expected, however if d == 0which looks like an Integeris truethan 'intuitively' d.equals(0)should also be true.

感谢您的快速答复。我认为它的装箱方式不同,真正的问题是:为什么它的装箱方式不同?我的意思是,这将是更直观,如果d == 0d不是d.equals(0d)非常直观和预期,但是如果d == 0它看起来像一个Integertrue不是“直觉”d.equals(0)也应该是真实的。

回答by Jigar Joshi

just change it to

只需将其更改为

System.out.println(d.equals(0d)); // is false ?! now true

You were comparing double with Integer0

您正在将 double 与Integer0进行比较

Under the cover

在封面下

System.out.println(d.equals(0)); // is false ?!

0will be autoboxed to Integerand an instance of Integer will be passed to equals()method of Doubleclass, where it will compare like

0将被自动装箱,Integer并且 Integer 的实例将被传递给类的equals()方法Double,在那里它会比较像

@Override
    public boolean equals(Object object) {
        return (object == this)
                || (object instanceof Double)
                && (doubleToLongBits(this.value) == doubleToLongBits(((Double) object).value));
    }

which is going to return falseof course.

这当然会返回false

Update

更新

when you do comparison using ==it compares values so there is no need to autobox , it directly operates on value. Where equals()accepts Objectso if you try to invoke d1.equals(0), 0is not Object so it will perform autoboxing and it will pack it to Integer which is an Object.

当您使用==它进行比较时,它会比较值,因此无需自动装箱,它直接对值进行操作。如果您尝试调用,那么equals()接受的地方不是 Object,因此它将执行自动装箱,并将其打包为 Integer,这是一个 Object。Objectd1.equals(0)0

回答by fortran

Numberobjects only equal to numbers with the same value if they are of the same type. That is:

Number如果对象类型相同,则对象仅等于具有相同值的数字。那是:

new Double(0).equals(new Integer(0));
new BigInteger("0").equals(new BigDecimal("0"));

and similar combinations are all false.

而类似的组合都是假的。

In your case, the literal 0is boxed into an Integerobject.

在您的情况下,文字0被装箱到一个Integer对象中。

回答by duedl0r

It's probably worth noting that you should compare floating point numbers like this:

可能值得注意的是,您应该像这样比较浮点数:

|x - y| < ε, ε very small

回答by Suraj Chandran

d.equals(0): 0is an int. The Double.equals()code will return true only for Doubleobjects.

d.equals(0):0是一个int。该Double.equals()代码将仅对Double对象返回 true 。

回答by Peter Lawrey

When you perform

当你执行

d == 0

this is upcast to

这是向上看

d == 0.0

however there are no upcasting rules for autoboxing and even if there were equals(Object) gives no hits that you want a Double instead of an Integer.

但是,没有自动装箱的向上转换规则,即使有 equals(Object) 也不会给出您想要 Double 而不是 Integer 的命中。