Memory reference [duplicate] - java

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 2 years ago.
Is c point to a or is c point to the same memory that a is pointing to?
Why does the following code print "We are equal"?
Thanks in advance
public static void main(String args[]) {
String a = "10";
String b = "10";
String c = a;
if(c.equals(b)) {
System.out.println("We are equal ");
}
else {
System.out.println("Not equal! ");
}
}

Java stores objects by reference... the reference just happens to be the value when we use primitives.
int is a primitive so
a == c => true
a == b => true
b == c => true
With Strings the situation is slightly different. Strings are effectively char arrays: char[] but are not considered primitive types in Java.. so:
"str1" == "str1" => false since you're comparing two object references now.
For this reason the Object class has the equals() method which allows you to compare reference objects (non-primitives) via something other than the object reference ID. The String (a subclass of Object.class) class overrides the equals method.
In your example (above) you say:
So why is ab==abc false. They are both pointing to same address.
This is incorrect. ab points to String that is "meowdeal" and abc points to a String that is also "meowdeal"... but crucially they are two distinct instances. Therefore:
ab==abc => false - here your checking for reference equality - are they the same object reference (no they are not)
ab.equals(abc) => true - here you're checking for string equality (is ab's "meowdeal" the same as abc's "meowdeal" - yes it is.
This is one of those curveball interview questions you might get from time to time so worth being aware of.

Related

Comparing Same Object of String with '==' and getting different result in both scenerio, where the String Object Value is same [duplicate]

This question already has answers here:
String.equals versus == [duplicate]
(20 answers)
How do I compare strings in Java?
(23 answers)
Closed 7 years ago.
In Program 1 I have declared two String and initialized them as "MADAM". When running I am checking the equality of their reference variable (by '==' operator') then I am getting a "true" response.
But in Program 2 I am declaring a String 'S' and initialize it as "MADAM". After that i am running a reverse loop and storing the characters of 'S' in reverse order in other String variable. Now i have again tried to check the equality of reference variable (by '==' operator') and am getting the response as 'false'. As both the String objects are of same value and are stored in constant Pool Area so both the variable should equate and the output in both the scenario should be 'true'. But WHY it is not same?
Program 1:
class Reverse {
public static void main(String[] args) {
String s="MADAM"; String rev="MADAM"; System.out.println(s==rev);
}
}
Output - true
Program 2:
class Reverse {
public static void main(String[] args) {
String s="MADAM"; String rev="";
for(int x=s.length()-1;x>=0;x--) { rev+=s.charAt(x); }
System.out.println(s==rev);
}
}
Output- false
In program 1 java compiler saves "MADAM" string in one memory location and assigns both "s" and "rev" to that location hence "s==rev" returns true because they both refer to the same address.
you should use "equals()" method to compare two strings. e.equals(rev);
have a look at this question:
Java String.equals versus ==
In your first class both strings are initialize to same object. So both are pointing to same memory location.
Next class, Rev is intilialized to "" value and see to madam so both have got different memory location. So false.
In essence,
if you use == for comparison, you are comparing their identity.
If you want to compare the object's value, use .equals()
String s="MADAM"; String rev="MADAM"; System.out.println(s==rev);
The above code will return true, because both Strings will be stored in the same memory location.
However, you can try the following, it will return you false:
String s1 = "aaa";
String s2 = new String("aaa");
System.out.println(s1 == s2); //false (comparing memory location)
System.out.println(s1.equals(s2)); //true (comparing value)
Side note: It is generally a bad practice to create Strings using new String(""). It was only used for demonstration purposes only.

Difference between substring and string in java [duplicate]

This question already has answers here:
Java: Why can String equality be proven with ==?
(3 answers)
Closed 8 years ago.
class test {
public static void main(String[] args) {
String a = "Hiabc";
String b = "abc";
String c = "abc";
System.out.println(a.substring(2,5)==b);
System.out.println(b==c);
}
}
output:
false
true
As far as I understand, Java's == look for addresses of the two compared objects. Yet, I don't understand why b==c is true because they must have different addresses. Also, if b==c, then why is a.substring(2,5), which is "abc" == b false?
As far as I understand, Java's == look for addresses of the two compared objects.
Almost correct. Java uses references not addresses, e.g. a reference is strongly typed: See https://softwareengineering.stackexchange.com/questions/141834/how-is-a-java-reference-different-from-a-c-pointer
why b==c is true
The variable b and c are initialized with the same string reference, because they reference the same string literal "abc".
why doesn't substring expression reference the string literal "abc"?
Because the javadoc of substring() says
Returns a new string that is a substring of this string.
So the method does not ensure that a reference to a string from the constant pool is returned. If you want this you have to do
a.substring(2,5).intern()
and than
a.substring(2,5).intern()==b
will be true.
Never compare strings with == in Java.
Use .equal or .equalIgnoreCase methods instead.
The difference between a.substring(2,5) and b is because substring created another String object and it's on a different location than b. It's not about the characters ...

Integer Comparison Results Vary in Java [duplicate]

This question already has answers here:
Integer wrapper class and == operator - where is behavior specified? [duplicate]
(2 answers)
Closed 8 years ago.
I am a novice Java programmer and came across a very weird scenario, as below.
public static void main(String[] args) {
Integer a = 500;
Integer b = 500;
// Comparing the values.
a <= b; // true
a >= b; // true
a == b; // false
// Reassigning the values
a = 50;
b = 50;
// Again comparing the values.
a <= b; // true
a >= b; // true
a == b; // true
}
My question is why do the results of a == b vary by varying values?
The answer to this question lies within the understanding of Autoboxing specified by Java programming language.
The variation in results of a == b happens because any integer between -128 to 127 are cached by the Integer class. When an int within this range is created it is retrieved from IntegerCache rather than creating a new Integer object.
Is this a bug? Of course not!
The Java class Integer is also called wrapper class because it provides an object that wraps an int primitive data type. In Java, comparing two value object is not straight forward. We should override the Object.equal method (and also the Object.hashCode) and use it to determine when two objects are equal. Using the == operator, in this case, we’re comparing the two physical object addresses. Java requires the new operator to create objects, which will be all stored on the JVM’s Heap. Local variables are stored on the JVM’s Stack, but they hold a reference to the object, not the object itself.
In first case when we check if a == b, we’re actually checking if both the references are pointing at the same location. Answer to this is NO!
But what happens when a & b are 50? To answer this we should have a look at the below Integer.valueOf method.
public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}
We are using the Autoboxing Java function through this Integer.valueOf method to compare a == b. With the aim of optimizing the resources use, the Integer class maintains a cache memory of Integer instances. This way, all the new Integer requests with a value between -128 and IntegerCache.high (configurable) will return an identical object allocated once. So, when we ask if a == b, we get true because, behind the scene, a and b are pointing to the same memory location.
Now another question arises: Does this approach involve in instance sharing problems? The answer fortunately is no, because Integer was defined as an immutable object and that means if you want to modify it, you have to get a new instance… exciting, isn’t it?
Shishir
Yes . Because values from a range of -127 to 128 will be stored in cache . so use equals and compare .
Java has interned the values from -128 to 127.
This is why you receive true when you compare two Integer objects in this range with ==.

Passing value of a string in an array to a method in java? [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 9 years ago.
thank you for taking the time to read this. Sorry if my question is dumb, I tried searching but couldn't quite figure out why I'm having this problem. I was trying to test some code for another application, but I'm having issues. Perhaps I just don't understand arrays properly.
I have a method named halfStepUp in a class named Transpose that, for testing purposes, should return "c#" if given "c" and "d#" if given "d". This is the code:
public class Transpose{
public static String halfStepUp(String note){
String n = null;
if (note == "c") n = "c#";
if (note == "d") n = "d"#;
return n;
}
}
I have the following code in my main method:
String [] scale = new String[2];
scale[0] = "c";
scale[1] = "d";
System.out.println(Transpose.halfStepUp(scale[0]));
This prints "null." What am I doing wrong?
I know the method works because if I use
System.out.println(Transpose.halfStepUp("c"));
It works fine. The solution is probably embarrassingly easy but I couldn't find a good way to word it when searching for help.
Thanks again for reading, and any answers are greatly appreciated!
To add a little more info to the answers you already got:
Java has two types of storage. One is the stack, which includes variable names and their values. One is the heap, that is just a huge collections of free-floating objects.
Now, if you're working with primitive types (like int, boolean or char), assigning a variable like
int myInt = 1;
pushes that variable on thje stack - the name is myInt, the value is 1.
If you, however, have an object (like strings are), assigning a variable does a little bit more.
String myString = "Hey!";
now creates an object (instance of String) somewhere on the heap. It has no name there, only some address in the memory where it can be found.
In addition to that, it pushes a variable on the stack. The name is myString - and the value is the address of the object on the heap.
So why is this relevant to comparing variables? Because == compares values of variables. ON THE STACK, that is. SO if you compare primitive types, everything works as expected. But if you're comparing Objects, == still only compares the values of the variables - which is, in that case, the addresses to the objects. If the addresses are the same, it returns true. That does mean, both variables point to the same object. If the addresses are different, == returns false., Without ever looking at the heap, where the objects really are.
An example:
String a = new String("Hey!");
String b = a;
if (a == b) System.out.println("true");
else System.out.println("false");
will echo "true" - because both variables contain the same object.
String a = new String("Hey!");
String b = new String("Hey!");
if (a == b) System.out.println("true");
else System.out.println("false");
will echo "false" - because you have two objects on the heap now, and a points to the one, while b points to the other. So while the contents of both objects may be the same, the contents of a and b on the stack are different.
Therefore, to compare any object, always use .equals() if you want to compare contents, not instance-equality.
[Addendum]:
With strings, this is even more complicated. As you already found out already,
String a = "Hey!"; // mention the difference to the example above:
String b = "Hey!"; // I did NOT use the `String()` cosntructor here!
if (a == b) System.out.println("true");
else System.out.println("false");
will actually give you "true". Now why is THAT? One might think that we still create two objects. But actually, we are not.
String is immutable. That means, once a String has been created, it cannot be modified. Ever. Don'T believe that? Take a look!
String myString = "test"; // we create one instance of String here
myString += " and more"; // we create another instance of String (" and more")
// and append that. Did we modify the instance stored in
// myString now? NO! We created a third instance that
// contains "test and more".
Therefore, there is no need to create additional instances of String with the same content - which increases performance, as Strings are widely used, in masses, so we want to have as few of them as possible.
To archive that, the JVM maintains a list of String Objects we already created. And every time we write down a String literal (that is something like "Hey!"), it looks in that lists and checks if we already created an instance that has that value. If so, it returns a pointer to that exact same instance instead of creating a new one.
And THIS is, why "Hey!" == "Hey!" will return true.
You should use the .equals() method when comparing strings, not ==. The == operator compares the references to see if they are pointing to the same underlying object. The .equals() method, compares the underlying objects to each other to see if they are semantically equivalent.
Try this instead: (edited from comments)
public class Transpose{
public static String halfStepUp(String note){
String n = null;
if ("c".equals(note)) n = "c#"; //using .equals as a string comparison
if ("d".equals(note)) n = "d#"; //not "d"#
return n;
}
}
The glitch is in this line:
if (note == "c") n = "c#";
This compares strings by address, not by value. Try using "c".equals(note) instead.
class Transpose{
public static String halfStepUp(String note){
String n = null;
if (note == "c") n = "c#";
if (note == "d") n = "d#";
return n;
}
}
public class TransposeTest {
public static void main(String... args) {
String [] scale = new String[2];
scale[0] = "c";
scale[1] = "d";
System.out.println(Transpose.halfStepUp(scale[0]));
}
}
working code

Why program will print "true" "true"? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why are these == but not `equals()`?
why this code will print
true
true
public class Test {
public static void main(String[] args){
String st1 = "abc";
String st2 = "abc";
Integer k1 = 100;
Integer k2 = 100;
System.out.println(st1 == st2);
System.out.println(k1 == k2);
}
}
To compare objects we use method equals(). But why it is ok in this way?
== compares object references. Because of you're Strings being hardcoded, they are interned and both use the same reference, therefor the 1st true. Also Integer caches commonly used numbers, so both of your Integers also reference the same object, which makes the second reference comparison true.
1) Both strings will be treated as string literals which will be interned and stored to same memory location.
== checks for reference equality, so both references point to same object and returns true.
2) Integer instances are cached for small range that is why k1 == k2 returns true for 100.
System.out.println(st1 == st2);
st1 is stored in the string constant pool (when first created); when the compiler sees st2="abc" it will just point st2 to the previously created object in the string constant pool.
i.e., st1 and st2 point to the same object ("abc") in the String constant pool and == operator checks if two reference variables point to the same object.
System.out.println(k1 == k2);
In this case, your wrapper instances are cached to small range thus == returns true.

Categories

Resources