25

I know that Double is a a wrapper class, and it wraps double number. 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 :

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

I cannot explain why Double make directly comparison wrong. Please explain for me.

Ivar
  • 6,138
  • 12
  • 49
  • 61
hqt
  • 29,632
  • 51
  • 171
  • 250
  • 11
    Use `c.equals(d)` instead of `==`. `==` only checks references. – Baz Sep 01 '12 at 09:59
  • 3
    @Baz Ah, I understand. Double is a class. It will compare object rather than compare value. This problem likes when we do with `String`. should use `equals` instead of `==` :) – hqt Sep 01 '12 at 10:00
  • 2
    Another difference is Double allow null value but double not. – Eric Tan Nov 25 '20 at 10:41

5 Answers5

33

c and d are technically two different objects and == operator compares only references.

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).

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()):

This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range.

Why valueOf()? Because this method is implicitly used to implement autoboxing:

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

See also

Community
  • 1
  • 1
Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
  • Oh. I have understand. this problem likes when we do with string class. But your second example is interesting. Can you tell me why it true when do with integer :) – hqt Sep 01 '12 at 10:02
  • @hqt: check out the links in *See also* section of my answer. – Tomasz Nurkiewicz Sep 01 '12 at 10:03
  • 1
    @hqt you can call it integer pool. Sized <-128,127> - All Integer within this range are equal using both `equals()` and `==` – dantuch Sep 01 '12 at 10:05
  • Oh. Nice link :) I don't know why many people here know this kind of knowledge. I don't see this in any Java book before. (about integer pol :) ) – hqt Sep 01 '12 at 10:06
  • 1
    I suppose Jon remembers this better :), so the range is from -128 to 127 (not -256 -> 255 as I wrote earlier). With a total numbers of 256, which is exactly **byte** range. – dantuch Sep 01 '12 at 10:09
  • 1
    @hqt Try some book preparing for SCJP / OCPJP certificate. You'll find it pretty fast ;) Or just read Effective Java (I think it's there too) – dantuch Sep 01 '12 at 10:11
  • Be *VERY* careful comparing floating-point numbers. The subject is a mine-field. See http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm and http://floating-point-gui.de/references/ and references therein. – Reb.Cabin Aug 19 '15 at 17:15
6

When applied to expressions of a class type, == will always perform a reference comparison (JLS section 15.21.3). So this line:

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

is checking whether c and d refer to the same objects. Auto-boxing in Java always (I believe) creates a new object for float and double (the situation is more complicated for integral types1). Therefore c and d refer to different objects, and so it prints false.

If you want to compare objects for equality, you need to call equals explicitly:

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

With double, it's using numeric equality instead - as specified in section 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. 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.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    About integer cache, can you tell me why you can know this ? I don't see this stuff in any java book I have read. ( and I don't think you learn all Java spec :D) – hqt Sep 01 '12 at 10:10
  • @hqt Even if you don't know all of the spec by heart, after a while you know most of it. And it is a good practice that whenever you see something that you don't know how it works you go and check the specs and / or the source. The new knowledge makes you a better developer and reduces the risk for bugs. – Roger Lindsjö Sep 01 '12 at 14:41
4

Use equals() to checks the equality of 2 objects. == checks if the 2 references refer to the same object in the memory.

Eng.Fouad
  • 115,165
  • 71
  • 313
  • 417
2

Content checking is only reliable for == when checking primitive types. For objects types it is always better to use the equals method:

c.equals(d)
Reimeus
  • 158,255
  • 15
  • 216
  • 276
1

Difference between == and 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.
  2. for object reference data types == refers to their references. Thus what the object points to in memory.

Consider case 1

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

*output is * true

enter image description here

case 2: == reference data types

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

*output is * false

enter image description here

d1 and d2 have different memory references.

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.

Therefore

Java uses == to compare primitives and for checking if two variables refer to the same object

`equals'

is used for checking if two objects are equivalent.

it also depends on the implementation of the object it is being called on. For Strings, equals() checks the characters inside of it.

    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.

case 1 will not compile

enter image description here

malvern dongeni
  • 647
  • 4
  • 10