why "==" working differently for integer and strings reference? [duplicate] - java

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 7 years ago.
May I know how == works here?
public class App {
public static void main(String[] args) {
String s1 = new String("str");
String s2 = new String("str");
System.err.println("why it,s "+String.valueOf(s1==s2));
int i1 = new Integer(10);
int i2 = new Integer(10);
System.err.println("why it,s "+String.valueOf(i1==i2));
}
}
When I am comparing references of two different String with the same values, then == says that they are not equal, but when I am comparing references of two integers with the same values, then == says that they are equal. Why is it so?

Ok, a more meaningful compare would be
public class App{
public static void main(String[] args) {
String s1 = new String("str");
String s2 = new String("str");
System.err.println("why it,s "+String.valueOf(s1==s2));
Integer i1 = new Integer(10);
Integer i2 = new Integer(10);
System.err.println("why it,s "+String.valueOf(i1==i2));
}
}
int is primitive, and == will just compare the value. Integer is an object, and == for objects is only true if it points to the same place in memory, otherwise it will be false. For primitives (int, boolean, etc...) == will test the value.
int i = Integer(10) is really int i = (Integer(10)).intValue(), java just does it automagically.
Edited to add more explanation:
Java has 2 types of types. Primitive types and Class types. A primitive type is just the value of the type: an int primitive type is just that, and int. There are not methods or anything, it just is an int.
If you say int a = 4, a is a primitive variable that points to a memory address that contains an int. That's it.
A Class type is a java object, so Integer is a class type. It represents an integer value, so Integer a = new Integer(4) would create an integer object, and a would point to a memory location that contains the object that new... created.
What's different?
Good question. In the latter example (new Integer(4)) this is an integer and some other stuff, stuff like a toString() method and some other stuff.
So, a recap:
A primitive is a value stored in memory somewhere.
A class is an object stored in memory somewhere, and in the case of Integer it represents an int but it has some other stuff associated with it (i.e. the `toString() method).
Now, == is a test for equivalency. So int == int checks to see if the primitive value is the same, since that is the only information that a primitive type has.
== for objects does mean something. Since an object points to a more than just a 4 or 8 or -1, the == only returns true if the object variables point to the same place in memory. If it does not, then you get false.
So:
int i = 1;
int j = 1;
Integer k = new Integer(1)
Integer l = new Integer(1)
Integer m = k;
Integer n = new Integer(k)
i == j -> true
k == l -> false
k == k -> true
k == l -> true
n == m -> false
n.intValue() == m.intValue() -> true (intValue returns a primitive type)
Now, .equals is a test to see if two objects are equal, which means different things for different objects.
For an Integer, a.equals(b) is true if the intValue()s are the same for a and b. However, a == b is true if a and b point at the same object in memory
Now, thing about an object that has 2 integers in it (like an x,y coordinate).

Related

Casting a primitive vs Creating a object of the primitive

I'm not habitual to casting a primitive data type to an object. Saw some code like:
public static int CompareAges(Person p1, Person p2) {
Integer age1 = p1.getAge();
return age1.compareTo(p2.getAge());
}
The instantiation of age1 seemed extraneous, so I tried to write the code as:
public static int CompareAges(Person p1, Person p2) {
return p1.getAge().compareTo(p2.getAge());
}
But that raised a compiler error because p1.getAge() is a primitive data type int and not an Integer, which is an object.
Intuitively, I did:
public static int CompareAges(Person p1, Person p2) {
return ((Integer) p1.getAge()).compareTo(p2.getAge());
}
and it worked!
The question: What did I miss? Since when did we start casting primitives as value types?
It's what happens internally:
1. Integer age1 = p1.getAge();
Integer != int
Integer = Integer.valueOf(int)
Integer age1 = Integer.valueOf(p1.getAge());
2. p1.getAge().compareTo(p2.getAge());
int.compareTo(int)
^^^
// it's just a primitive type, as a result - the compile error
3. ((Integer) p1.getAge()).compareTo(p2.getAge())
Integer.compareTo(int)
Integer.compareTo(Integer.valueOf(int))
((Integer) p1.getAge()).compareTo(Integer.valueOf(p2.getAge()))
4. (Integer) p1.getAge() ---> Integer.valueOf(p1.getAge())
// why so? look at callOfCode's answer
But, in my opinion, ((Integer) p1.getAge()).compareTo(p2.getAge()) looks ugly.
I would replace it to
p1.getAge() > p2.getAge() ? 1 : (p1.getAge() < p2.getAge() ? -1 : 0)
or to
Integer.compare(p1.getAge(), p2.getAge()) // java 7+
I wouldn't like to do casting in this case.
More about "autoboxing/unboxing" you may find here.
Each primitive has its own boxing type
The Boxing could be implicit (Autoboxing) or explicit like you did it in your code.
p2.getAge() is an Example of AutoBoxing or Implicit Boxing. The method compareTo takes an Object. As it is a primitive, Java converts it automatically to the correspondent Boxing Object (Integer). You did the explicit Boxing with the cast (Integer) p1.getAge()
Difference between new Integer(primitive); and Integer integer = (Integer)primitive; Is only on bytecode level. In the first case, new object of Integer class is created in memory. In the second case, Integer.valueOf(primitive) is called internally. This is the static method that checks if primitive falls into range of -128 to 127 and if it falls, it returns value from integer cache and no new object is being created. If it not falls into that range, new Integer object is instantiated. It is used for efficiency. But such efficiency is unsignificant novadays.
int z = 1;
Integer a = (Integer)z;
Integer b = (Integer)z;
//Prints true, since Integer object is retrieved from cache (range of -128 to 127)
System.out.println(a == b);
int w = 999;
Integer c = (Integer)w;
Integer d = (Integer)w;
//Prints false, since 999 is not in cache, new Integer objects are instantiated and they points to different places in memory
System.out.println(c == d);

How the comparisons are taking place in the code below [duplicate]

This question already has answers here:
int vs Integer comparison Java [duplicate]
(2 answers)
Closed 7 years ago.
public class Application {
public static void main(String[] args) {
Integer a = new Integer(10);
Integer b = new Integer(10);
int x = new Integer(10);
int y = new Integer(10);
int p = 10;
int q = 10;
System.out.println(a == b);
System.out.println(a == x);
System.out.println(x == p);
System.out.println(b == q);
System.out.println(y == q);
System.out.println(x == y);
}
}
The above code produces the output:
false
true
true
true
true
true
Please explain the process of primitive type getting compared to a reference type using == ?
how int x = new Integer(10); getting evaluated internally?
Integer a = new Integer(10);
Integer b = new Integer(10);
a==b ---> Reference variable a is compared to the reference variable b. Not the object they point to. And those two reference variables are indeed, different. Hence, false. Use .equals() to compare objects.
a==x ---> auto-unboxing. x contains the value 10. during comparison, Integer is compared to int. When wrapper is compared to premitive, auto-unboxing occurs. a becomes an int. And so, effectively 10 is compared to 10. Hence true.
x==p,b==q,y==q,x==y --> Same. Auto-unboxing, taking effect. Hence all true.
Whenever Java compares a wrapper class variable with a primitive variable, it unboxes the wrapper class variable into a primitive, and then compares them.
Compile this with SDK previous to Java 5, and I doubt if it would compile at all. Java introduced this feature from Java 5. If I can remember correctly..
When you compare the primitive int with its wrapper class Integer, the wrapper is unboxed to its primitive value. That is why you are getting true always except first condition.
In the first condition, your are checking the reference equality of two different objects, which will be false obviously.
== for classes compares references. When you make 2 objects with the same values you should use .equals() because 2 object the are instantiated with new will have different references. When using int it compares the values because they are primitives and passing in new Integer() into an int is creating a primitive int.

Java: Store int in Integer array

Can you store int values into a Integer array?
Given an array:
Integer[] array = new Integer[10];
Are the following two statements equivalent?
Integer x = new Integer(1);
array[0] = x;
int x = 1;
array[0] = x;
They are not 100% equivalent. The following should be equivalent however:
Integer x = Integer.valueOf(1);
array[0] = x;
int x = 1;
array[0] = x;
Note that the int primitive gets autoboxed to the Integer wrapper class. So you're not storing an int primitive in the Integer array, but an Integer object.
You should hardly ever use the Integer constructor (which always creates a new object) but use one of its static factory methods or autoboxing (less code), which allow to cache instances (since they are immutable).
Once the values are inside the array itself, they are both values of type Integer. If you pass a primitive object to an instance of its wrapper class, then that primitive type is autoboxed, meaning its automatically converted to the type of its wrapper class.
Integer x = 4; //autoboxing: "4" is converted to "new Integer(4)"
Likewise, a wrapper class type can is unboxed when it is passed to a primitive type:
int x = new Integer(4); //unboxing: "new Integer(4)" is converted to primitive int 4
For your purposes, both examples your wrote will work.

Find max element in Java ArrayList

I have such simple code:
import java.util.ArrayList;
import java.util.List;
public class Main {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Integer[] tab = {2324,1,2,2324,3,45,1,5,0,9,13,2324,1,3,9,8,4,2,1};
Integer max = 2324;
List<Integer> indexes = new ArrayList<Integer>();
for (int e = 0; e < tab.length; e++) {
if (tab[e] == max) {
indexes.add(new Integer(e));
System.out.println("Found max");
}
}
}
}
The main problem here is I want to find every index in my tab where the max value is. For now on, it doesnt work - it doesnt display Found max message even once, although it should do it 3 times. Wheres the problem?
Ok, this finally worked, thanks all of you people:
public static void main(String[] args) {
Integer[] tab = {2324,1,2,2324,3,45,1,5,0,9,13,2324,1,3,9,8,4,2,1};
Integer max = 2324;
List<Integer> indexes = new ArrayList<Integer>();
for (int e = 0; e < tab.length; e++) {
if (tab[e].intValue() == max.intValue()) {
indexes.add(Integer.valueOf(e));
System.out.println("Found max");
}
}
}
Change
Integer[] tab = {2324,1,2,2324,3,45,1,5,0,9,13,2324,1,3,9,8,4,2,1};
to
int[] tab = {2324,1,2,2324,3,45,1,5,0,9,13,2324,1,3,9,8,4,2,1};
Integer objects are only precached for the values from -128 to 127.
If you want to leave it Integer you can change
if (tab[e] == max) {
to
if (tab[e].equals(max)) {
because it will then check for object equality, and not reference equality.
That's because you are comparing with == and not equals.
You are using the == operator in something that it is not the primitive int, but an instance of class Integer. Basically, you are comparing the references of both objects, which are different. Try using :
if(tab[e].equals(max))
The basic problem you have is that you are using Integer, not int One difference being that as Integer is an object == compares the references to two different objects. (Not he contents of those objects)
I suggest you use primitives like int instead of objects where you can.
You can only compare primitive values with ==. Since Integer is an object, change tab[e] == max to tab[e].equals(max).
Look for equals vs ==
Also read: Java: int vs integer
The JVM is caching Integer values.
== only works for numbers between -128 and 127
See explanation here: http://www.owasp.org/index.php/Java_gotchas#Immutable_Objects_.2F_Wrapper_Class_Caching
try this:
if (tab[e].intValue() == max.intValue()) {
or
if (tab[e].intValue() == max) {
If you are using Integer object rather than primitive int, then with comparison operator like == , atleast one operand should be primitive one (other will be converted implicitly).
Or you should use equals method for equality
Use one of the three : 1. tab[e].intValue() == max or 2. int max = 2324; or 3. Use equals() method of Integer class.

How to cast an Object to an int

How can I cast an Object to an int in java?
If you're sure that this object is an Integer :
int i = (Integer) object;
Or, starting from Java 7, you can equivalently write:
int i = (int) object;
Beware, it can throw a ClassCastException if your object isn't an Integer and a NullPointerException if your object is null.
This way you assume that your Object is an Integer (the wrapped int) and you unbox it into an int.
int is a primitive so it can't be stored as an Object, the only way is to have an int considered/boxed as an Integer then stored as an Object.
If your object is a String, then you can use the Integer.valueOf() method to convert it into a simple int :
int i = Integer.valueOf((String) object);
It can throw a NumberFormatException if your object isn't really a String with an integer as content.
Resources :
Oracle.com - Autoboxing
Oracle.com - Primitive Data types
On the same topic :
Java: What's the difference between autoboxing and casting?
Autoboxing: So I can write: Integer i = 0; instead of: Integer i = new Integer(0);
Convert Object into primitive int
Scenario 1: simple case
If it's guaranteed that your object is an Integer, this is the simple way:
int x = (Integer)yourObject;
Scenario 2: any numerical object
In Java Integer, Long, BigInteger etc. all implement the Number interface which has a method named intValue. Any other custom types with a numerical aspect should also implement Number (for example: Age implements Number). So you can:
int x = ((Number)yourObject).intValue();
Scenario 3: parse numerical text
When you accept user input from command line (or text field etc.) you get it as a String. In this case you can use Integer.parseInt(String string):
String input = someBuffer.readLine();
int x = Integer.parseInt(input);
If you get input as Object, you can use (String)input, or, if it can have an other textual type, input.toString():
int x = Integer.parseInt(input.toString());
Scenario 4: identity hash
In Java there are no pointers. However Object has a pointer-like default implementation for hashCode(), which is directly available via System.identityHashCode(Object o). So you can:
int x = System.identityHashCode(yourObject);
Note that this is not a real pointer value. Objects' memory address can be changed by the JVM while their identity hashes are keeping. Also, two living objects can have the same identity hash.
You can also use object.hashCode(), but it can be type specific.
Scenario 5: unique index
In same cases you need a unique index for each object, like to auto incremented ID values in a database table (and unlike to identity hash which is not unique). A simple sample implementation for this:
class ObjectIndexer {
private int index = 0;
private Map<Object, Integer> map = new WeakHashMap<>();
// or:
// new WeakIdentityHashMap<>();
public int indexFor(Object object) {
if (map.containsKey(object)) {
return map.get(object);
} else {
index++;
map.put(object, index);
return index;
}
}
}
Usage:
ObjectIndexer indexer = new ObjectIndexer();
int x = indexer.indexFor(yourObject); // 1
int y = indexer.indexFor(new Object()); // 2
int z = indexer.indexFor(yourObject); // 1
Scenario 6: enum member
In Java enum members aren't integers but full featured objects (unlike C/C++, for example). Probably there is never a need to convert an enum object to int, however Java automatically associates an index number to each enum member. This index can be accessed via Enum.ordinal(), for example:
enum Foo { BAR, BAZ, QUX }
// ...
Object baz = Foo.BAZ;
int index = ((Enum)baz).ordinal(); // 1
Assuming the object is an Integer object, then you can do this:
int i = ((Integer) obj).intValue();
If the object isn't an Integer object, then you have to detect the type and convert it based on its type.
#Deprecated
public static int toInt(Object obj)
{
if (obj instanceof String)
{
return Integer.parseInt((String) obj);
} else if (obj instanceof Number)
{
return ((Number) obj).intValue();
} else
{
String toString = obj.toString();
if (toString.matches("-?\d+"))
{
return Integer.parseInt(toString);
}
throw new IllegalArgumentException("This Object doesn't represent an int");
}
}
As you can see, this isn't a very efficient way of doing it. You simply have to be sure of what kind of object you have. Then convert it to an int the right way.
You have to cast it to an Integer (int's wrapper class). You can then use Integer's intValue() method to obtain the inner int.
Answer:
int i = ( Integer ) yourObject;
If, your object is an integer already, it will run smoothly. ie:
Object yourObject = 1;
// cast here
or
Object yourObject = new Integer(1);
// cast here
etc.
If your object is anything else, you would need to convert it ( if possible ) to an int first:
String s = "1";
Object yourObject = Integer.parseInt(s);
// cast here
Or
String s = "1";
Object yourObject = Integer.valueOf( s );
// cast here
I use a one-liner when processing data from GSON:
int i = object != null ? Double.valueOf(object.toString()).intValue() : 0;
If the Object was originally been instantiated as an Integer, then you can downcast it to an int using the cast operator (Subtype).
Object object = new Integer(10);
int i = (Integer) object;
Note that this only works when you're using at least Java 1.5 with autoboxing feature, otherwise you have to declare i as Integer instead and then call intValue() on it.
But if it initially wasn't created as an Integer at all, then you can't downcast like that. It would result in a ClassCastException with the original classname in the message. If the object's toString() representation as obtained by String#valueOf() denotes a syntactically valid integer number (e.g. digits only, if necessary with a minus sign in front), then you can use Integer#valueOf() or new Integer() for this.
Object object = "10";
int i = Integer.valueOf(String.valueOf(object));
See also:
Inheritance and casting tutorial
int i = (Integer) object; //Type is Integer.
int i = Integer.parseInt((String)object); //Type is String.
Can't be done. An int is not an object, it's a primitive type. You can cast it to Integer, then get the int.
Integer i = (Integer) o; // throws ClassCastException if o.getClass() != Integer.class
int num = i; //Java 1.5 or higher
You can't. An int is not an Object.
Integer is an Object though, but I doubt that's what you mean.
If you mean cast a String to int, use Integer.valueOf("123").
You can't cast most other Objects to int though, because they wont have an int value. E.g. an XmlDocument has no int value.
I guess you're wondering why C or C++ lets you manipulate an object pointer like a number, but you can't manipulate an object reference in Java the same way.
Object references in Java aren't like pointers in C or C++... Pointers basically are integers and you can manipulate them like any other int. References are intentionally a more concrete abstraction and cannot be manipulated the way pointers can.
int[] getAdminIDList(String tableName, String attributeName, int value) throws SQLException {
ArrayList list = null;
Statement statement = conn.createStatement();
ResultSet result = statement.executeQuery("SELECT admin_id FROM " + tableName + " WHERE " + attributeName + "='" + value + "'");
while (result.next()) {
list.add(result.getInt(1));
}
statement.close();
int id[] = new int[list.size()];
for (int i = 0; i < id.length; i++) {
try {
id[i] = ((Integer) list.get(i)).intValue();
} catch(NullPointerException ne) {
} catch(ClassCastException ch) {}
}
return id;
}
// enter code here
This code shows why ArrayList is important and why we use it. Simply casting int from Object. May be its helpful.
For Example Object variable; hastaId
Object hastaId = session.getAttribute("hastaID");
For Example Cast an Object to an int,hastaID
int hastaID=Integer.parseInt(String.valueOf(hastaId));
Refer This code:
public class sample
{
public static void main(String[] args)
{
Object obj=new Object();
int a=10,b=0;
obj=a;
b=(int)obj;
System.out.println("Object="+obj+"\nB="+b);
}
}
so divide1=me.getValue()/2;
int divide1 = (Integer) me.getValue()/2;
We could cast an object to Integer in Java using below code.
int value = Integer.parseInt(object.toString());
If you want to convert string-object into integer...
you can simply pass as:
int id = Integer.valueOf((String) object_name);
Hope this will be helpful :-)
Integer x = 11
int y = x.intValue();
System.out.println("int value"+ y);
Finally, the best implementation for your specification was found.
public int tellMyNumber(Object any) {
return 42;
}
first check with instanceof keyword . if true then cast it.

Categories