This question already has answers here:
Java: Integer equals vs. ==
(7 answers)
Closed 8 years ago.
Please can you explain the below behaviour.
public class EqAndRef {
public static void main(String[] args) {
Integer i = 10;
Integer j = 10;
Double a = 10D;
Double b = 10D;
System.out.println(i.equals(j));
System.out.println(i == j);
System.out.println(a.equals(b));
System.out.println(a == b);
}
}
Output on jdk 6
true
true
true
false
why a==b is false and i==j not false?
The Integers i and j are constructed (via auto boxing) from integer literals from the range –128 to 127 and thus are guaranteed to be pooled by the JVM so the same object (see flyweight pattern) is used for them. Hence, they compare identical by object references.
For the Doubles a and b on the other hand, no such pooling guarantee exists and, in your case, you got two different objects that did not compare identical.
Using == to compare objects if you don't mean to check identity is to be considered suspect and should be avoided. The equals methods of both types are overridden to compare the boxed values (as opposed to object identity) which is why they return true in both cases (and should be used).
Initialize the Integers the following way then you will get the difference as #5gon12eder said
The Integer s i and j are constructed (via auto boxing) from integer literals from the range –128 to 127 which are guaranteed to be pooled by the JVM so the same object (see flyweight pattern ) is used for them. Hence, they compare equal by object references.
try this code to initialize your integers
Integer i = new Integer(10);
Integer j = new Integer(10);
Related
This question already has answers here:
Why is 128==128 false but 127==127 is true when comparing Integer wrappers in Java?
(8 answers)
Closed 1 year ago.
class MyClass {
public static void main(String[] args) {
Integer a = 5;
Integer b = 5;
Integer c = 129;
Integer d = 129;
System.out.println(a == b);
System.out.println(c == d);
}
}
The output is
true
false
Why is this happening?
When using Integer wrapper objects instead of the int primitive, java globally caches these objects in this range because they are used often. This can speed up execution. Because these objects are cached, they are equal, while above the threshold a new objects is created of every integer.
When you want to compare Integers instead of ints use the .equals() method instead of ==.
This question already has answers here:
Java: Integer equals vs. ==
(7 answers)
How can I properly compare two Integers in Java?
(10 answers)
Closed 4 years ago.
Consider:
Integer i = 11;
Integer j = 11;
Integer h = 10000;
Integer k = 10000;
System.out.println((i==j));
System.out.println((i.equals(j)));
System.out.println((h==k));
System.out.println((h.equals(k)));
The output is:
true
true
false
true
Actually for h==k, it should also give true. What is the explanation?
Because == checks object references while equals checks actual values. They are not guaranteed to yield the same result.
In some cases they do give the same result, but that's because your JVM is interning some of the Integer objects. Meaning, it maintains a cache of integer objects. So for example if you ask for an Integer value of 10, it might return the same object instance. But there are no guarantees as to which values would be interned. So it is always advisable to use equals instead of relying on ==.
This question already has answers here:
How != and == operators work on Integers in Java? [duplicate]
(5 answers)
Closed 8 years ago.
In a program I was working on, I ran into a data storage issue, specifically related to ArrayLists. This is not the actual code I was testing, but it provides an example of what I mean.
public class test
{
public static void test()
{
ArrayList<Integer> bob = new ArrayList<Integer>();
bob.add(129);
bob.add(129);
System.out.println(bob.get(0) == 129 );
System.out.println(bob.get(1) == 129 );
System.out.println(bob.get(0) == bob.get(1) );
}
}
If you run it, you get, true, true, and false. The code recognizes that both are equal to 129 but for some reason returns false when it attempts to see if they are equal to each other. However, if you change the value to 127, it returns true, true, and true. Testing this multiple times for different values and you will see that the minimum value to receive true, true, and true is -128 and the maximum is 127. This is the interval for byte, which leads me to suspect that the == operation uses byte in this case.
What is interesting is that if you modify the code so that it reads
public class test
{
public static void test()
{
ArrayList<Integer> bob = new ArrayList<Integer>();
bob.add(129);
bob.add(129);
int a = bob.get(0);
int b = bob.get(1);
System.out.println(a == 129 );
System.out.println(b == 129 );
System.out.println(a == b );
}
}
it works just as intended. true, true, and true are outputted. Why does saving the values as int before the comparison change the outcome? Is it because if they are not saved, the comparison will use byte by default for the == comparison?
The answer lies in the caching mechanism of the primitive wrapper classes that Java employs.
In the case of an Integer, there's caching for the values between -128 to 127 (i.e. the value range of a byte).
This means that if you box any value between -128 to 127, you get a ready made instance from the cache. This is why the == operator works for those, as it compares the references rather than the values.
On the other hand, if you're using any other value, you'll get a fresh new instance per boxing, which means that the == operator will fail.
Here's the piece of code from the Integer class that's responsible for this:
private static class IntegerCache {
private IntegerCache(){}
static final Integer cache[] = new Integer[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Integer(i - 128);
}
}
Right, I just realized that I can explain this. Don't know what I was thinking earlier.
JLS, section 5.1.7:
If the value p being boxed is an integer literal of type int between -128 and 127 inclusive (§3.10.1), or the boolean literal true or false (§3.10.3), or a character literal between '\u0000' and '\u007f' inclusive (§3.10.4), then let a and b be the results of any two boxing conversions of p. It is always the case that a == b.
As 129 falls outside this range, you'll end up with two distinct Integer objects in indices 1 and 2, unless you configure the range yourself using JVM flags.
For the last comparison in the first bit of code: As ArrayList#get() returns an object of the type the ArrayList is parameterized with, that last comparison is comparing two Integer objects, and as the two objects are distinct, the result will be false. The first two comparisons result in the Integer objects being unboxed, because you're comparing an Integer wrapper to an int literal, so the results are as you expect.
The second bit of code works as you expect because you're comparing int literals, and those comparisons are more intuitive.
Autoboxing and unboxing are at work, this works -
bob.add(129); // Autoboxed to Integer
int a = bob.get(0); // primitive int a
int b = bob.get(1); // primitive int b
System.out.println(a == 129 ); // primitive to primitive
System.out.println(b == 129 ); // primitive to primitive
System.out.println(a == b ); // primitive to primitive
You could also use Integer.intValue(),
Integer a = bob.get(0);
Integer b = bob.get(1);
// Here you could omit one, but not both, calls to intValue()
System.out.println(a.intValue() == b.intValue()); // primitive to primitive
This is because first two comparisons are on int values because bob.get() is getting casted to int before comparison. in the third, comparison is on Objects and that is the reason you are getting false for values outside -128 to 127 because in this range values are cached.
Hope this helps.
Collections have 2 get methods that accept int and Integer with Integer collections, autoboxing is doing some internal magic to use the wrong method (Effective Java)
Use explicit boxing or unbox as necessary.
That's because the third test compares two objects because the (Integer object) return of the get() calls are not unboxed. The values for which the result is true are using cached singletons and therefore the same object, but outside of that range new and distinct objects are put into the list by auto-boxing.
Take note that this behavior could vary from JVM to JVM and version to version; on some JVMs it could even be dynamic based on some heuristic - for example, the system could conceivably look at available memory and cache 16 bit values instead of 8.
This question already has answers here:
Why is 128==128 false but 127==127 is true when comparing Integer wrappers in Java?
(8 answers)
Closed 6 years ago.
The following code seemed really confusing to me since it provided two different outputs.The code was tested on jdk 1.7.
public class NotEq {
public static void main(String[] args) {
ver1();
System.out.println();
ver2();
}
public static void ver1() {
Integer a = 128;
Integer b = 128;
if (a == b) {
System.out.println("Equal Object");
}
if (a != b) {
System.out.println("Different objects");
}
if (a.equals(b)) {
System.out.println("Meaningfully equal.");
}
}
public static void ver2() {
Integer i1 = 127;
Integer i2 = 127;
if (i1 == i2) {
System.out.println("Equal Object");
}
if (i1 != i2){
System.out.println("Different objects");
}
if (i1.equals(i2)){
System.out.println("Meaningfully equal");
}
}
}
Output:
[ver1 output]
Different objects
Meaningfully equal.
[ver2 output]
Equal Object
Meaningfully equal
Why the == and != testing produces different results for ver1() and ver2() for same number much less than the Integer.MAX_VALUE? Can it be concluded that == checking for numbers greater than 127 (for wrapper classes like Integer as shown in the code) is totally waste of time?
Integers are cached for values between -128 and 127 so Integer i = 127 will always return the same reference. Integer j = 128 will not necessarily do so. You will then need to use equals to test for equality of the underlying int.
This is part of the Java Language Specification:
If the value p being boxed is true, false, a byte, or a char in the range \u0000 to \u007f, or an int or short number between -128 and 127 (inclusive), then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.
But 2 calls to Integer j = 128 might return the same reference (not guaranteed):
Less memory-limited implementations might, for example, cache all char and short values, as well as int and long values in the range of -32K to +32K.
Because small integers are interned in Java, and you tried the numbers on different sides of the "smallness" limit.
There exist an Integer object cache from -128 and up to 127 by default. The upper border can be configured. The upper cache border can be controlled by VM option -XX:AutoBoxCacheMax=<size>
You are using this cache when you use the form:
Integer i1 = 127;
or
Integer i1 = Integer.valueOf(127);
But when you use
Integer i1 = new Integer(127);
then you're guaranteed to get a new uncached object. In the latter case both versions print out the same results. Using the cached versions they may differ.
Java caches integers from -128 to 127 That is why the objects ARE the same.
I think the == and != operators when dealing with primitives will work how you're currently using them, but with objects (Integer vs. int) you'll want to perform testing with .equals() method.
I'm not certain on this, but with objects the == will test if one object is the same object or not, while .equals() will perform testing that those two objects contain equivalence in value (or the method will need to be created/overridden) for custom objects.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Integer wrapper objects share the same instances only within the value 127?
I have copied the following program snippet from the Khalid Mughal SCJP, but I am unable to
understand the output.
public class RQ200_60 {
public static void main(String[] args) {
Integer i = -10;
Integer j = -10;
System.out.print(i==j); // output: true -- why true?
System.out.print(i.equals(j)); // output: true
Integer n = 128;
Integer m = 128;
System.out.print(n==m); // output: false
System.out.print(n.equals(m)); // output: true
}
}
The above program giving output true for the first print statement but it supposed to give false because it is reference comparison with == relational operator. But third print gives false and I don't understand this inconsistency.
Explanations are greatly appreciated!
In the first case, both the objects i and j are pointing to the same cached object. By default, the range between -128 and 127 are cached as Integer Object. We can increase the range using JVM arguments
The answers about caching are correct. However, if you go...
Integer i = new Integer(10);
Integer j = new Integer(10);
...then you avoid the caching and the results will be what you expected.
Integer objects may be cached for the ones that represent a value close to 0. (The specification for the implementation may tell you some details). This is presumably to save memory (values close to 0 are common, and it would waste a lot of memory to make a new object for every variable with the same value).
== checks whether two things are the same object; you may or may not have the same Integer object for any two given variables with the same value. You are not supposed to check with == because you are not supposed to care whether it is the same object; it is the value of an Integer that matters, not its identity.
Here in this case the Integer i and Integer j holding the integer values which are in range of integer, range of an Integer is -128 to 128, and Integer n and Integer m exceeds the range of Integer