0

I was working on Java ArrayList of Integers. However, I found that after certain negative int value; Collection of Type <Integer> start behaving weirdly with == operator.

Please see the code below:

import java.util.*;

public class JavaWeirdness
{

    public static void main(String[] args)
    {
        for(int i=0;i>=-200;i--)
        {
            ArrayList<Integer> list = new ArrayList<>();

            list.add(i);
            list.add(i);
            System.out.println("For i = "+ i);
            System.out.println((list.get(0) == list.get(1)));
        }
    }

}

When i <= -129 then it prints false for every value.

Thus it puzzled me; Is it because of Refrence Type Integer instead of primitive int?

As If we change:

list.get(0) == list.get(1);

To:

(int) list.get(0) == (int) list.get(1));

Everything starts working fine.

OR

Even if we use .equals() instead of == it works fine.

like:

list.get(0).equals(list.get(1));

BUT

My question here is: WHY? Is it happening in first place?

is it because of auto-boxing and unboxing?

Or

is it because of buffer issues? If you closely observe it is -((2^7)+1) and onwards.

Or

is it because of collections issues?

Or

is it a bug? (I don't think that'll be the case)

Or

is it because of some IEEE number standards?

Or

anything else?

This is kinda weird; However, I hope experts here will help me out.

PS. please don't ask why I've written this weird code (Let us say I was just testing something :P :D)

Vedant Terkar
  • 4,553
  • 8
  • 36
  • 62
  • Read more here: https://wiki.owasp.org/index.php/Java_gotchas#Immutable_Objects_.2F_Wrapper_Class_Caching – Nishant Feb 16 '20 at 10:00
  • I have also answered another related question before : https://stackoverflow.com/questions/53939403/hashmap-get-operator-returning-false/53939542#53939542 – Adrian Shum Feb 16 '20 at 10:03
  • @AdrianShum, I'm definitely not asking difference between `==` and `equals` or contract between `hashcode` and `equals` here. Anyway, https://stackoverflow.com/questions/1700081/why-is-128-128-false-but-127-127-is-true-when-comparing-integer-wrappers-in-ja This Really Answers This question. – Vedant Terkar Feb 16 '20 at 10:11
  • @VedantTerkar Please do read my answer carefully. Especially the "Final Answer" part. I am basically answering same thing as the question you have quoted. In brief, autoboxing will make use of `Integer.valueOf()`for which is caching `Integer` instances for small input value (which caused `==` to "work") – Adrian Shum Feb 17 '20 at 02:02

1 Answers1

-2

== on objects refers to an equality of same instance. On primitive int it refers on same value equals is the right chiice to compare Integer, or Long or String or other based on values. Not a problemi with collections

abatti
  • 155
  • 7
  • Then why it works for `-128 == -128`? – Vedant Terkar Feb 16 '20 at 10:01
  • 4
    @Vedant The duplicate explains. It's due to a cache of `Integer` objects in the byte range. – Slaw Feb 16 '20 at 10:02
  • Try to print the toString method result – abatti Feb 16 '20 at 10:03
  • @Slaw oh.. Thanks Man! You can close this one or tell me how to do it. – Vedant Terkar Feb 16 '20 at 10:04
  • The ```==``` operator compares if the values on left and right side are the same. In case of simple numeric types (int, float, double) this compares the values. In case of references to objects, the ```==``` operator compares if both references point to the same object (not different objects with same value). The method ```Object.equals()``` does the same but all numeric classes (e.g. Integer and String) have an overridden variant of that method which compares their values instead of the object references. Therefore ```Integer.equals()``` is different than ```Object.equals()```. – Stefan Feb 16 '20 at 10:07