what is difference between integer a = 5 and new Integer(5)? - java

if i write below code(in java):
Integer a =new Integer(5);
Integer b=new Integer(5);
if(a==b){
System.out.println("In ==");
}
if(a.equals(b)){
System.out.println("In equals");
}
My output is: "In equals"
But if i change first and second line to ->
Integer a =5;
Integer b=5;
then my o/p is:
In ==
In equals
So what is difference in creating a Integer object? How it gets created when we do Integer a =5?
Does it mean that a and b object refer to same object, if i create Integer a=5 and creates another object Integer b=5 ?

Integer a = 5; is called autoboxing, compiler converts this expression into actual
Integer a = Integer.valueOf(5);
For small numbers, by default -128 to 127, Integer.valueOf(int) does not create a new instance of Integer but returns a value from its cache. So here
Integer a = 5;
Integer b= 5;
a and b point to the same Object and a == b is true.

In Java, you should never use the new Integer, even though it is valid syntax it is not the best way to declare integers as you have found out. Use instead Integer.valueOf(int) This has multiple advantages.
You are not creating extra objects needlessly. Whenever you use the new operator you are forcing the vm to create a new object which is not needed in most cases. valueOf(int) will return a cached copy. Since Integer objects are immutable this works great. This means that you can use == though in practice you should use a null safe compare like in Apache ObjectUtils
The == operator tests for equality. References are only equal when they refer to the same object in memory. equals method ensures 2 object instances are 'equivalent' to each other.
Integer a = new Integer(5);
Integer b = a;
a == b; // true!
a.equals(b); // true
b = new Integer(5);
a == b; // false
a.equals(b); // true
Primitives are equal whenever their value is the same.
int a = 5; int b = a;
a == b; // true!

for primitive data types like int the equality operator will check if the variables are equal in value
for reference data types like your java.lang.Integer objects, the equality operator will check if the variables reference the same object. In the first case, you have two "new" and separate integer objects, so the references are different

Integer wrapper shares few properties of String class. In that it is immutable and that can be leveraged by using intern() like functionality.
Analyse this:
String a = "foo";
String b = "foo";
String c = new String("foo");
String d = new String("foo");
a == b //true
c == d //false
The reason is when JVM creates a new String object implicitly it reuses existing String object which has the same value "foo", as in case a and b.
In your case JVM implicitly auto-boxes the ints and re-uses existing Integer object. Integer.valueOf() can be used explicitly to re-use existing objects if available.

I believe when you create using new operator it creates object reference. In first case, there are two object references and they are not same but their value is same. That is not the situation in second case.

Related

Integer caching in Java with new operator

In the below class I have tried to compare the wrapper class with the primitive but the results are different.
I have checked the following links links:
The more interesting question is why new Object(); should be required to create a unique instance every time? i. e. why is new Object(); not allowed to cache? The answer is the wait(...) and notify(...) calls. Caching new Object()s would incorrectly cause threads to synchronize with each other when they shouldn't.
If there is a new object then how are a and c equal?
If b is equal to c and c is equal to a, then a should be equal to b. But in following case I got a != c.
Please explain.
class WrapperCompare {
public static void main (String args[]) {
Integer a = new Integer(10);
Integer b = 10;
int c=10;
System.out.println(b==c); //true
System.out.println(a==b); //false
System.out.println(a==c); //true
}
}
Update:
By referring to this link Integer caching.
Basically, the Integer class keeps a cache of Integer instances in the range of -128 to 127, and all autoboxing, literals and uses of Integer.valueOf() will return instances from that cache for the range it covers.
So in this case all statements should be true.
Explanation
When you compare Integer vs int with ==, it needs to convert the Integer to an int. This is called unboxing.
See JLS§5.1.8:
If r is a reference of type Integer, then unboxing conversion converts r into r.intValue()
At that point, you are comparing int vs int. And primitives have no notion of instances, they all refer to the same value. As such, the result is true.
So the actual code you have is
a.intValue() == c
leading to a comparison of 10 == 10, both int values, no Integer instances anymore.
You can see that new Integer(...) indeed creates new instances, when you compare Integer vs Integer. You did that in a == b.
Note
The constructor new Integer(...) is deprecated. You should instead use Integer#valueOf, it is potentially faster and also uses an internal cache. From the documentation:
Returns an Integer instance representing the specified int value. If a new Integer instance is not required, this method should generally be used in preference to the constructor Integer(int), as this method is likely to yield significantly better space and time performance by caching frequently requested values. This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range.
The caching is important to note here, since it yields to == being true again (for cached values):
Integer first = Integer.valueOf(10);
Integer second = Integer.valueOf(10);
System.out.println(first == second); // true
The caching is guaranteed for values between -128 and +127, but may also be used for others.
Also note that your b actually comes out of the cache, since
Integer b = 10;
// same as
Integer b = Integer.valueOf(10);
// and not
Integer b = new Integer(10);
So boxing goes through Integers cache (see JLS§5.1.7).

Java operators -> how == operator works

Java operator == is used for reference comparison
then how can == be used for comparing int a =1; and int b = 1;
both values are stored in different locations then how it compares
As commented by Andy, the JLS states that the operator '==' is indeed used for reference type comparison but also for numeric type and Boolean type comparison.
int is a numeric type.
When comparing numeric types the values are compared (not the references).
However if you want to determine if the references of two integers are equal rather than the values then you can use the Integer class. This class simply wraps the primitive numeric type int.
Now consider the following code:
public class TestClass {
public static void main(String[] args)
{
Integer A = new Integer(1);
Integer B = new Integer(1);
Integer C = A;
if (A == B) System.out.println("Won't print."); // (1)
if (A.equals(B)) System.out.println("WILL Print!!!"); // (2)
if (A == C) System.out.println("WILL Print!!!"); // (3)
}
}
Because A and B are objects, the reference of A is compared to the reference of B. Even though their int values are the same, because they are independent references this statement is false.
The equals method compares the int values of each Integer object and thus is true.
Integer object C references object A. Hence this reference comparison will be true.

equals only when put into variables

I have two values to be compared. They appear to be not equal when compared directly using the == operator, but equal after they are put into local variables. Could anyone tell me why?
The code is as follows:
(MgrBean.getByName(name1).getId() == MgrBean.getByName(name2).getId()),
//This one is false,
int a = MgrBean.getByName(name1).getId();
int b = MgrBean.getByName(name2).getId();
(a == b); //This one is true.
I believe your getId() is returning an Integer instead of int.
Integer is the wrapper class for int primitive type. If you compare object reference using ==, you are comparing if they are referring to same object, instead of comparing the value inside. Hence if you are comparing two Integer objects reference, you are not comparing its integer value, you are simply checking if that two reference is pointing to same Integer object.
However, if you use a primitive type to store that value (e.g. int a = ....getId()), there is auto-unboxing happening, and that wrapper object is converted to primitive type value, and comparing primitive type values using == is comparing the value, which do the work you expect.
Suggested further reading for you:
Primitive Type vs Reference Type in Java
Auto-boxing and unboxing in Java
The most misconception about Integer type happens everywhere including other answers here
Suppose you have two integers defined as follows:
Integer i1 = 128
Integer i2 = 128
If you then execute the test (i1 == i2), the returned result is false. The reason is that the JVM maintains a pool of Integer values (similar to the one it maintains for Strings). But the pool contains only integers from -128 to 127. Creating any Integer in that range results in Java assigning those Integers from the pool, so the equivalency test works. However, for values greater than 127 and less than -128), the pool does not come into play, so the two assignments create different objects, which then fail the equivalency test and return false.
In contast, consider the following assignments:
Integer i1 = new Integer(1); // Any number in the Integer pool range
Integer i2 = new Integer(1); // Any number in the Integer pool range
Because these assignments are made using the 'new' keyword, they are new instances created, and not picked up from the pool. Hence, testing (i1== i2) on the preceding assignments returns false.
Here's some code that illustrates the Integer pool:
public class IntegerPoolTest {
public static void main(String args[]){
Integer i1 = 100;
Integer i2 = 100;
// Comparison of integers from the pool - returns true.
compareInts(i1, i2);
Integer i3 = 130;
Integer i4 = 130;
// Same comparison, but from outside the pool
// (not in the range -128 to 127)
// resulting in false.
compareInts(i3, i4);
Integer i5 = new Integer(100);
Integer i6 = new Integer(100);
// Comparison of Integers created using the 'new' keyword
// results in new instances and '==' comparison leads to false.
compareInts(i5, i6);
}
private static void compareInts(Integer i1, Integer i2){
System.out.println("Comparing Integers " +
i1 + "," + i2 + " results in: " + (i1 == i2) );
}
}

operator == differet behaviour on wrapper class object

can Any body explain me what is happeing in the output.
If == is use to compare two ref. variable it simply check its reference if they are same then it enter in if body, then why the hell
aa==bb is equal if creting static method valueOf() and ee==ff is not equal (which is ok) if creating its object using new keyword ?
static void main(String args[])
{
Integer aa = Integer.valueOf("12");
Integer bb = Integer.valueOf("12");
if(aa==bb)System.out.println("aa==bb");
if(aa!=bb)System.out.println("aa!=bb");
Integer ee = new Integer("12");
Integer ff = new Integer("12");
if(ee==ff)System.out.println("ee==ff");
if(ee!=ff)System.out.println("ee!=ff");
}
Output :
aa==bb
ee!=ff
The == comparator checks for object equality!
Since Integer.valueOf maintains a cache of Integer Objects with the value -128 to 127 valueOf(String) returns the cached object, thus the == comparance results in true.
Integer a1 = new Integer("12");
Integer b1 = new Integer("12");
//a1 == b1 returns false because they point to two different Integer objects
Integer aa = Integer.valueOf("12");
Integer bb = Integer.valueOf("12");
//aa == bb returns true because they point to same cached object
For the comparance of object values always use the .equals method, for primitives like int, long etc. you can use the == comparator.
Because Integer.valueOf maintains cache of integers from -128 to 127
Here is the source code of valueOf you can clearly see that it returns same object if Integer value is between -128 to 127
public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}
so your == returns true. If value is more than that then it will always return you false.
Integer aa = Integer.valueOf("1200");
Integer bb = Integer.valueOf("1200");
aa == bb --> false
You should always check equality using equals method
ee.equals(ff);
If you add another if with below
if (ee.equals(ff))
System.out.println("ee equals ff");
Output will be
ee equals ff
For ee and ff two objects of Integer are created on heap hence both of them are referencing different objects so they are not equal when using == operator.
new Integer("12") creates a new Integer object with value 12. No matter how times you do that you are creating a brand new object each time. That's why == doesn't work in the second case.
The JVM maintains a cache of the Integer objects for values that are believed to be used more frequently (-128 - 127). Integer.valueOf("12") behind the scene does the same thing (new Integer("12")), but before doing that it checks in that cache if for that value the object already exists in the cache, if it does then that's what it returns, otherwise it creates a new one, adds it to the cache and returns it. That's why == works in the first case.
Also, for objects, == should never be used for equality checks, instead they should be used only for identity checks (e.g. to see if two different variables are referring to the same object). For equality check always use the equals method.

Why Java does not see that Integers are equal?

I have integers that are supposed to be equal (and I verify it by output). But in my if condition Java does not see these variables to have the same value.
I have the following code:
if (pay[0]==point[0] && pay[1]==point[1]) {
game.log.fine(">>>>>> the same");
} else {
game.log.fine(">>>>>> different");
}
game.log.fine("Compare:" + pay[0] + "," + pay[1] + " -> " + point[0] + "," + point[1]);
And it produce the following output:
FINE: >>>>>> different
FINE: Compare:: 60,145 -> 60,145
Probably I have to add that point is defined like that:
Integer[] point = new Integer[2];
and pay us taken from the loop-constructor:
for (Integer[] pay : payoffs2exchanges.keySet())
So, these two variables both have the integer type.
Check out this article: Boxed values and equality
When comparing wrapper types such as Integers, Longs or Booleans using == or !=, you're comparing them as references, not as values.
If two variables point at different objects, they will not == each other, even if the objects represent the same value.
Example: Comparing different Integer objects using == and !=.
Integer i = new Integer(10);
Integer j = new Integer(10);
System.out.println(i == j); // false
System.out.println(i != j); // true
The solution is to compare the values using .equals()…
Example: Compare objects using .equals(…)
Integer i = new Integer(10);
Integer j = new Integer(10);
System.out.println(i.equals(j)); // true
…or to unbox the operands explicitly.
Example: Force unboxing by casting:
Integer i = new Integer(10);
Integer j = new Integer(10);
System.out.println((int) i == (int) j); // true
References / further reading
Java: Boxed values and equality
Java: Primitives vs Objects and References
Java: Wrapper Types
Java: Autoboxing and unboxing
If they were simple int types, it would work.
For Integer use .intValue() or compareTo(Object other) or equals(Object other) in your comparison.
In java numeric values within range of -128 to 127 are cached so if you try to compare
Integer i=12 ;
Integer j=12 ; // j is pointing to same object as i do.
if(i==j)
print "true";
this would work, but if you try with numbers out of the above give range they need to be compared with equals method for value comparison because "==" will check if both are same object not same value.
There are two types to distinguish here:
int, the primitive integer type which you use most of the time, but is not an object type
Integer, an object wrapper around an int which can be used to use integers in APIs that require objects
when you try to compare two objects (and an Integer is an object, not a variable) the result will always be that they're not equal,
in your case you should compare fields of the objects (in this case intValue)
try declaring int variables instead of Integer objects, it will help
The condition at
pay[0]==point[0]
expression, uses the equality operator == to compare a reference
Integer pay[0]
for equality with the a reference
Integer point[0]
In general, when primitive-type values (such as int, ...) are compared with == , the result is true if both values are identical. When references (such as Integer, String, ...) are compared with == , the result is true if both references refer to the same object in memory.
To compare the actual contents (or state information) of objects for equality, a method must be invoked.
Thus, with this
Integer[] point = new Integer[2];
expression you create a new object that has got new reference and assign it to point variable.
For example:
int a = 1;
int b = 1;
Integer c = 1;
Integer d = 1;
Integer e = new Integer(1);
To compare a with b use:
a == b
because both of them are primitive-type values.
To compare a with c use:
a == c
because of auto-boxing feature.
for compare c with e use:
c.equals(e)
because of new reference in e variable.
for compare c with d it is better and safe to use:
c.equals(d)
because of:
As you know, the == operator, applied to wrapper objects, only tests whether the objects have identical memory locations. The following comparison would therefore probably fail:
Integer a = 1000;
Integer b = 1000;
if (a == b) . . .
However, a Java implementation may, if it chooses, wrap commonly occurring values into identical objects, and thus the comparison might succeed. This ambiguity is not what you want. The remedy is to call the equals method when comparing wrapper objects.

Categories