简体   繁体   English

比较 double 和 Double 之间的区别

[英]Difference between double and Double in comparison

I know that Double is aa wrapper class, and it wraps double number.我知道Double是一个包装类,它包装double数。 Today, I have seen another main difference :今天,我看到了另一个主要区别:

double a = 1.0;
double b = 1.0;
Double c = 1.0;
Double d = 1.0;
System.out.println(a == b);  // true
System.out.println(c == d);  // false

So strange with me !!!对我来说太奇怪了!!!

So, if we use Double , each time, we must do something like this :所以,如果我们使用Double ,每次都必须这样做:

private static final double delta = 0.0001;
System.out.println(Math.abs(c-d) < delta); 

I cannot explain why Double make directly comparison wrong.我无法解释为什么 Double 直接比较是错误的。 Please explain for me.请为我解释。

c and d are technically two different objects and == operator compares only references. cd在技​​术上是两个不同的对象,而==运算符只比较引用。

c.equals(d)

is better as it compares values, not references.更好,因为它比较值,而不是参考。 But still not ideal.但还是不理想。 Comparing floating-point values directly should always take some error (epsilon) into account ( Math.abs(c - d) < epsilon ).直接比较浮点值应始终考虑一些错误(epsilon)( Math.abs(c - d) < epsilon )。

Note that:注意:

Integer c = 1;
Integer d = 1;

here comparison would yield true , but that's more complicated ( Integer internal caching, described in JavaDoc of Integer.valueOf() ):这里比较会产生true ,但这更复杂( Integer内部缓存,在Integer.valueOf() JavaDoc中描述):

This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range.此方法将始终缓存 -128 到 127(含)范围内的值,并且可能缓存此范围之外的其他值。

Why valueOf() ?为什么是valueOf() Because this method is implicitly used to implement autoboxing:因为这个方法隐式用于实现自动装箱:

Integer c = Integer.valueOf(1);
Integer d = Integer.valueOf(1);

See also也可以看看

When applied to expressions of a class type, == will always perform a reference comparison ( JLS section 15.21.3 ).当应用于类类型的表达式时, ==始终执行引用比较( JLS 第 15.21.3 节)。 So this line:所以这一行:

System.out.println(c == d); 

is checking whether c and d refer to the same objects.正在检查cd是否引用相同的对象。 Auto-boxing in Java always (I believe) creates a new object for float and double (the situation is more complicated for integral types 1 ). Java 中的自动装箱总是(我相信)为floatdouble创建一个新对象(整数类型1的情况更复杂)。 Therefore c and d refer to different objects, and so it prints false .因此cd指的是不同的对象,因此它打印false

If you want to compare objects for equality, you need to call equals explicitly:如果要比较对象是否相等,则需要显式调用equals

System.out.println(c.equals(d));

With double , it's using numeric equality instead - as specified in section 15.21.1 .对于double ,它使用数字相等代替 - 如第 15.21.1 节中所述 Hence the difference in behaviour.因此,行为上的差异。


1 For integral autoboxing, "small" values are cached - so autoboxing 5 (say) will return the same reference every time. 1对于完整的自动装箱,“小”值被缓存 - 所以自动装箱 5(比如说)每次都会返回相同的引用。 The definition of "small" is implementation-specific, but it's guaranteed within the range -128 to 127. See the bottom of section 5.1.7 for details. “小”的定义是特定于实现的,但保证在 -128 到 127 的范围内。有关详细信息,请参阅第 5.1.7 节的底部。

Use equals() to checks the equality of 2 objects.使用equals()检查 2 个对象的相等性。 == checks if the 2 references refer to the same object in the memory. ==检查 2 个引用是否指向内存中的同一个对象。

Content checking is only reliable for == when checking primitive types.检查原始类型时,内容检查仅对==可靠。 For objects types it is always better to use the equals method:对于对象类型,最好使用equals方法:

c.equals(d)

Difference between == and equals ==equals区别

using == on primitive data types is not the same as using it on object reference data types.在原始数据类型上使用==与在对象引用数据类型上使用它不同。

  1. On primitive data types == is used as equals .在原始数据类型上==用作equals
  2. for object reference data types == refers to their references.对于对象引用数据类型==指的是它们的引用。 Thus what the object points to in memory.因此对象指向内存中的内容。

Consider case 1考虑案例 1

    double d1 = 10.00;
    double d2 =10.00;
    System.out.println(d1 == d2); 

*output is * true *输出是* true

在此处输入图片说明

case 2: == reference data types情况 2: ==引用数据类型

    Double d1 = 10.00;
    Double d2 =10.00;
    System.out.println(d1 == d2);

*output is * false *输出是* false

在此处输入图片说明

d1 and d2 have different memory references. d1 和 d2 具有不同的内存引用。

to check the validity of this consider the following code要检查它的有效性,请考虑以下代码

    Double d1 = 10.00;
    Double d2 = d1;
    System.out.println(d1 == d2);

This will print true since d1 and d2 point to the same memory reference.这将打印true因为 d1 和 d2 指向相同的内存引用。

Therefore所以

Java uses == to compare primitives and for checking if two variables refer to the same object Java使用==来比较原语并检查两个变量是否指向同一个对象

`equals' ‘等于’

is used for checking if two objects are equivalent.用于检查两个objects是否相等。

it also depends on the implementation of the object it is being called on.它还取决于它被调用的对象的实现。 For Strings , equals() checks the characters inside of it.对于Stringsequals()检查其中的字符。

    Double d1 = 10.00;
    Double d2 = 10.00;
    System.out.println(d1.equals(d2));

prints true since it looks what's inside the d1 and d2.打印为true因为它查看 d1 和 d2 中的内容。

case 1 will not compile情况 1不会编译

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM