-1

Edit: Some people stated that this is possible duplicate of one of question asking how to compare string values. I was asking about comparing double with int, that is why .equal() did not work.


First, I set a LinkedList of doubles with first element = -999

then if the comparison is

return listOfNumber.getFirst().equals(-999);

the outcome will be false.

However if the comparison is written as

return listOfNumber.getFirst()== -999;

Then the outcome will be true.

I thought .equals() compares the value and == compare the object and == can only take -128 to 127. So why exactly I cannot use .equals to compare doubles?

Also if the LinkedList is String with first element = "a" if I use

return ListOfString.getFirst() == "a";

then the outcome is false but if I use

return ListOfString.getFirst().equals("a");

then the outcome is true.

I am very confused why the comparison of double and string need to be different to yield correct result?

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
Bighuyou
  • 83
  • 2
  • 10
  • When comparing primitives you have to use `==`, if you are comparing objects you have to use `.equals()`. – vandench Apr 14 '18 at 18:59
  • 1
    Possible duplicate of [How do I compare strings in Java?](https://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java) – Austin Apr 14 '18 at 18:59
  • 1
    The first example fails cause `-999` is an `int`. `getFirst` returns a `Double`, whose `equals` methods requires `(obj instanceof Double)`. You can fix this by prefixing your number with `d`: `list.getFirst().equals(-999d)` – Vince Apr 14 '18 at 19:05
  • I suspect [Autoboxing](https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html) being at the core of this problem. Could you try `return -999 == listOfNumber.getFirst();`? – Turing85 Apr 14 '18 at 19:07
  • @Turing85 That returns `true`, same as his example of `list.getFirst() == -999` – Vince Apr 14 '18 at 19:17
  • Regarding the edit... `ListOfString.getFirst()` should **always** use `.equals`... Unless that's actually a list of numbers, not Strings – OneCricketeer Apr 14 '18 at 21:49

1 Answers1

4

Your problem is caused by autoboxing in Java.

Assuming (as you stated listOfNumber is a list of Double`):

ArrayList<Double> listOfNumber = new ArrayList<>();
listOfNumber.add(-999);

Since Java knows the signature of ... add(T) is ... add(Double), your add statement gets translated to:

listOfNumber.add(Double.valueOf(-999));

When you are executing

return listOfNumber.getFirst().equals(-999);

Java knows that Object.equals accepts a Object, and -999 fits an integer (the default type for a number), so it translates it to:

return listOfNumber.getFirst().equals(Integer.valueOf(-999));

Since a Integer and a Double aren't the same, it returns false, but for the == case, the java compilers gets smarter, and knows (double)-999 == (integer)-999

Ferrybig
  • 18,194
  • 6
  • 57
  • 79
  • "*java compilers gets smarter, and knows (double)-999 == (integer)-999*" This is not the case. The compiler will promote the integer to a double, so it wouldn't be "smart enough" to simply compare the two, rather it changes the representation of one of them to match. Check out [§5.6 Numeric Promotions](https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6)., more specifically, [§5.6.2 Binary Numeric Promotion](https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2) – Vince Apr 14 '18 at 19:08