I have some code which is effectively the following:
String a;
String b;
a = get_string_from_complex_procedure_1();
b = get_string_from_complex_procedure_2();
if (a != b)
{
put_up_error_dialog("["+a+"] != ["+b+"]");
}
The code is designed such that a and b should end up identical, and indeed most of the time they are, but occasionally I get the error dialog appearing. The confusing thing though, is that the two strings appear identical to me when reported by the dialog. I'm wondering what sort of things can cause this problem?
Rewrite like this:
String a;
String b;
a = get_string_from_complex_procedure_1();
b = get_string_from_complex_procedure_2();
if (!a.equals(b))
{
put_up_error_dialog("["+a+"] != ["+b+"]");
}
The == and != operators compare references, not values.
You cannot use == and != on Strings. To compare two Strings use a.equals(b) and !a.equals(b)
Use of == or != in case of String compares reference (memory location) so better you use equals() method.
use
a.equals(b); or a.equalsIgnoreCase(b) to compare String.
Related
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
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Difference Between Equals and ==
For example, if I have
MyClass foo = new MyClass();
MyClass bar = new MyClass();
if (foo == bar) {
// do something
}
if (foo < bar) {
// do something
}
if (foo > bar) {
// do something
}
how do foo and bar get compared? Does Java look for .compareTo() methods to be implemented for MyClass? Does Java compare the actual binary structure of the objects bit for bit in memory?
Very simply the arithmetic comparison operators == and != compare the object references, or memory addresses of the objects. >, and < and related operators can't be used with objects.
So ==, != is useful only if you want to determine whether two different variables point to the same object.
As an example, this is useful in an event handler: if you have one event handler tied to e.g. multiple buttons, you'll need to determine in the handler which button has been pressed. In this case, you can use ==.
Object comparison of the type that you're asking about is captured using methods like .equals, or special purpose methods like String.compareTo.
It's worth noting that the default Object.equals method is equivalent to ==: it compares object references; this is covered in the docs. Most classes built into Java override equals with their own implementation: for example, String overrides equals to compare the characters one at a time. To get a more specific/useful implementation of .equals for your own objects, you'll need to override .equals with a more specific implementation.
You didn't try it yourself, apparently, because <, >, <= and >= do not work on Objects.
However, == compares the left and right operand. When they are binary the same, it results in true. In the case of objects, in compares the pointers. So which means that this will only result in true if the Object is left and right the very same object in memory.
Other methods, like compareTo and equals are made to provide a custom method of comparing to different objects in memory, but which might be equal to each other (i.e. the data is the same).
In case of Strings, for example:
String str0 = new String("foo");
String str1 = new String("foo");
// A human being would say that the two strings are equal, which is true
// But it are TWO different objects in memory. So, using == will result
// in false
System.out.println(str0 == str1); // false
// But if we want to check the content of the string, we can use the equals method,
// because that method compares character by character of the two objects
String.out.println(str0.equals(str1)); // true
String.out.println(str1.equals(str0)); // true
No it doesn't. It compares whether the two variables are references to the same objects.
Unless you're dealing with types which are subject to autoboxing, such as Integer, you can't use > and < with objects at all.
In the case where you are using an autoboxed type, java doesn't look for specific methods, but will auto-unbox the variables, turning them into primitives - but this isn't the case for the equals operator. The == operator will always compare objects as references, even when comparing autoboxed objects:
Integer i1 = new Integer(10);
Integer i2 = new Integer(10);
if(i1 < i2) { // evaluates to false!
System.out.println("i1 is less than i2");
}
else if(i1 > i2) { // evaluates to false!
System.out.println("i1 is greater than i2");
}
else if(i1 == i2) { // evaluates to false!
System.out.println("i1 and i2 are equal");
}
else {
System.out.println("Um... well that's just confusingi");
}
It compares the reference value and will only return true if foo and bar point to the same object.
In Java, "==" compares the object identity. "new" is guaranteed to return a new object identity each time.
I'd actually love if "==" would call compareTo. Alas, it doesn't.
So I've heard that if I compare 2 strings with == then I will only get true back if they both refer to the same object/instance. That's strings. What about Booleans?
Does == check for full equality in Booleans? - Java
It depends on whether you're talking about Booleans (the object wrapper, note the capital B) or booleans (the primitive, note the lower case b). If you're talking about Booleans (the object wrapper), as with all objects, == checks for identity, not equivalence. If you're talking about booleans (primitives), it checks for equivalence.
So:
Boolean a, b;
a = new Boolean(false);
b = new Boolean(false);
System.out.println("a == b? " + (a == b)); // "a == b? false", because they're not the same instance
But
boolean c, d;
c = false;
d = false;
System.out.println("c == d? " + (c == d)); // "c == d? true", because they're primitives with the same value
Regarding strings:
I've heard that if I compare 2 strings with == then I will only get true back if the strings are identical and they both refer to the same object/instance...
It's not really an "and": == will only check whether the two String variables refer to the same String instance. Of course, one String instance can only have one set of contents, so if both variables point to the same instance, naturally the contents are the same... :-) The key point is that == will report false for different String instances even if they have the same characters in the same order. That's why we use equals on them, not ==. Strings can get a bit confusing because of interning, which is specific to strings (there's no equivalent for Boolean, although when you use Boolean.valueOf(boolean), you'll get a cached object). Also note that Java doesn't have primitive strings like it does primitive boolean, int, etc.
If you have an Object use equals,
when not you can run in things like this.
(VM cache for autoboxing primitives)
public static void main(String[] args){
Boolean a = true;
Boolean b = true;
System.out.println(a == b);
a = new Boolean(true);
b = new Boolean(true);
System.out.println(a == b);
}
the output is TRUE and FALSE
When using ( == ) with booleans,
If one of the operands is a Boolean wrapper, then it is first unboxed
into a boolean primitive and the two are compared.
If both are Boolean wrappers,created with 'new' keyword, then their
references are compared just like in the case of other objects.
new Boolean("true") == new Boolean("true") is false
If both are Boolean wrappers,created without 'new' keyword,
Boolean a = false;
Boolean b = Boolean.FALSE;
// (a==b) return true
It depends if you are talking about value types like: int, boolean, long or about reference types: Integer, Boolean, Long. value types could be compared with ==, reference types must be compared with equals.
I cannot see what I am doing wrong here. Here is the code I am having trouble with :
String tempSummaryString = "SUMMARY:";
for(int z = 0; z<attributeList.size() ; z++)
{
System.out.println(attributeList.get(z).substring(0,tempSummaryString.length()));
if(attributeList.get(z).length() > tempSummaryString.length() &&
attributeList.get(z).substring(0,tempSummaryString.length() == tempSummaryString)
{
event.setTitle(attributeList.get(z).substring(tempSummaryString.length(),attributeList.get(z).length()));
}
}
Now my problem is that the program never goes into the if (does not execute the event.setTitle method). When I print the value of
attributeList.get(z).substring(0,tempSummaryString.length())
I get the following:
SUMMARY:
So I am stumped about why it is not entering the if! I don't get it!
Hopefully someone can point out a stupid mistake I am making because I really dont know what else to do
You've fallen for the old == vs equals() problem. You are using ==, which unlike javascript, does an identity comparison (ie are these the same objects).
Try this:
attributeList.get(z).substring(0,tempSummaryString.length())
.equals(tempSummaryString) // equals() not ==
Also, you should consider using the foreach syntax for your loop:
for (String attribute : attributeList) {
if (attribute.substring... // forget about attributeList.get(z) and even z
}
Don't compare strings using the == operator (as in attributeList.get(z).substring(0,tempSummaryString.length()) == tempSummaryString), use the String.Equals method instead.
Your problem is this: attributeList.get(z).substring(0,tempSummaryString.length())== tempSummaryString. You compare references, not string contents. Use String.equals(otherString) to that end.
You should compare the Strings with equals().
attributeList.get(z).substring(0,tempSummaryString.length()).equals(tempSummaryString)
You're comparing strings with ==, while you should use the String class' .equals() method.
I have a query and a resultset
I do this
while (rs.next())
{
String string = rs.getString(ColumnName);
if (String == "certainvalue")
{
//perform action
}else {
//do nothing
}
My problem is that the if condition doesn't seem to be working.... even though I know "certainvalue" is in the result set, it never evaluates to true, and it never performs the action---- I am confused as to why that is...
is it because i am using a while loop?? or is it because resultsets are just wierd,, ,what is going on???
Java can't compare strings with ==. What you have to do is use the equals method of the String.
if (string.equals("certainvalue")) {
perform action
}
It looks you're using Java. In that case, the == operator compares if the two objects are the same, not if they represent the same value.
Rewrite the test :
if ("certainvalue".equals(string)) { doStuff(); }
(You might consider "a".equals(b) to be equivalent to b.equals("a"), but the first form protects you from a NullPointerException if there is no value for the row in the database.)
String is an object. You can't do a comparison that way (you are trying to compare object reference).
If you are use java(aren't you?) try:
String string = rs.getString(columnName);
if (string.compareTo("anotherString") == 0){
}
You can use operator == just for primitive types (like int).