Posted: Wed Oct 01, 2008 7:48 pm Post subject: Doing if-and-else with String variables
Hi
I'm new in Java and just started learning a month ago.
I have a problem using if-and-else with String variables. The statment never become true even if it equal to the variable. For example,
Quote:
String ans;
Scanner sc = new Scanner(System.in);
System.out.print("Enter Captal of Canada: ");
ans = sc.nextLine();
if (ans == "Ottowa") {
System.out.println("correct");
} else {
System.out.println("wrong");
Even if I enter Ottowa, it will still output wrong.
Can any1 help me here?
Sponsor Sponsor
McKenzie
Posted: Wed Oct 01, 2008 8:22 pm Post subject: Re: Doing if-and-else with String variables
Short Version:
You need if (ans.equals("Ottowa")) {
Long Version
String is a class, not a primative type so your variable ans is actually a reference to a spot in memory where the contents of your String lives. The String literal "Ottowa" lives at some other place in memory. When you use == you are doing a shallow comparison (comparing the value in your variable i.e. the reference/address) When you use .equals you do a deep comparison, meaning you comare the contents of the objects that are being refered to.
HellblazerX
Posted: Wed Oct 01, 2008 8:22 pm Post subject: Re: Doing if-and-else with String variables
You can't compare Strings like you do numbers. You'll need to use the compareTo () method. Basically, you'll have one of the two Strings call on the method, with the second String being passed in as the parameter. The method will return a 0 if the two are equal. So it'll look something like this:
code:
if (ans.compareTo ("Ottawa") == 0) {
edit: Oops, actually Mckenzie's method works better. Totally forgot about that one hehehe
S_Grimm
Posted: Tue Oct 07, 2008 7:10 pm Post subject: RE:Doing if-and-else with String variables
the ".equals" method is a hell of a lot easier
chili5
Posted: Tue Oct 07, 2008 7:40 pm Post subject: RE:Doing if-and-else with String variables
This always annoyed me, that you couldn't compare strings like you can in other languages. :s
Took me a little while to get used to using .equals.
Also, you can also use:
code:
if(answer.equalsIgnoreCase("Ottawa")) {
If you wish to not worry about casing.
Clayton
Posted: Tue Oct 07, 2008 9:34 pm Post subject: RE:Doing if-and-else with String variables
chili5 wrote:
his always annoyed me, that you couldn't compare strings like you can in other languages. :s
That's because you're never actually comparing strings in Java. You're comparing Strings, which makes all the difference. McKenzie explained why in his post, but I'll reiterate, using some example code:
Java:
publicclass Example { publicstaticvoid main (String[] args){ String name = "Bob";
String fool = "Bob";
if(name == fool) System.out.println("Something broke");
if(name.equals(fool)) System.out.println("It appears Bob is a fool");
} }
Now, when you run this code, the output will be "It appears Bob is a fool". Why is this? Because name is not equal to fool. The value contained in the variable name is different from the value in fool. Both name and fool are references to an object some place in memory. As such, the value that actually is contained in name and fool are memory locations to the contents of the object which it references. Therefore, with two distinct objects, name and fool will never be equal to each other, no matter what the string the object holds.
[Gandalf]
Posted: Tue Oct 07, 2008 9:37 pm Post subject: Re: RE:Doing if-and-else with String variables
chili5 @ 2008-10-07, 7:40 pm wrote:
This always annoyed me, that you couldn't compare strings like you can in other languages. :s
This stems from Strings being objects in Java and not primitive data types, hence when you use the equality operator you're checking if the references are the same, not the characters that make up the string. Really, this is another reason to stick with Ruby or Python before trying something like Java. Something as simple as strings requires a pretty good understanding of objects, memory management, references/pointers, even operator overloading.
Also, A\V, comments like that really aren't necessary. Are you really contributing anything to the topic by posting that?
Edit by Clayton: I win.
Edit by Gandalf: Perhaps, but I'm right!
Edit by Clayton: Only due to optimization!
[Gandalf]
Posted: Tue Oct 07, 2008 9:46 pm Post subject: Re: RE:Doing if-and-else with String variables
Clayton @ 2008-10-07, 9:34 pm wrote:
Now, when you run this code, the output will be "It appears Bob is a fool".
Actually, it will output:
Quote:
Bob is a fool
It appears Bob is a fool
Because they do refer to the same object. To get the output you would expect, you would have to do something like:
Java:
publicclass Example { publicstaticvoid main (String[] args){ String name = "Bob";
String fool = "Bobo".substring(0, 3);
if(name == fool) System.out.println("Bob is a fool");
if(name.equals(fool)) System.out.println("It appears Bob is a fool");
} }
Isn't Java just superb? A perfect introductory programming language!
Sponsor Sponsor
Clayton
Posted: Tue Oct 07, 2008 9:55 pm Post subject: RE:Doing if-and-else with String variables
They do not refer to the same object.
They refer to two different objects with the exact same properties, thus the two objects have different memory addresses, and thus, only "It appears Bob is a fool" should be output.
Take into account the following code:
Java:
publicclass TestClass { int bar;
boolean baz;
String foo;
public TestClass (int aBar, boolean aBaz, String aFoo){
bar = aBar;
baz = aBaz;
foo = aFoo;
} }
publicclass FooBar { publicstaticvoid main (String[] args){
TestClass qux = new TestClass (5, true, "compsci");
TestClass qat = new TestClass (5, true, "compsci");
System.out.println(qux == qat);
} }
Both of the objects are independent of each other, identical, yes, the same? No.
Tony
Posted: Tue Oct 07, 2008 9:56 pm Post subject: RE:Doing if-and-else with String variables
While Clayton is right, there is an exception that seriously blows the mind of students new to Java.
Due to compiler optimization, the memory location of string literal "Bob" is reused, so trivial examples could cause misleading results.
Quote:
tony$ javac -version
javac 1.5.0_13
tony$ java Example
Bob is a fool
It appears Bob is a fool
Though this outcome shouldn't be counted on. (Well maybe unless one knows their JVM, memory management, and compiler optimizations). Having the "fool" be stored at any other memory location
code:
String fool = new String("Bob");
Will produce the intended results:
Quote:
tony$ java Example
It appears Bob is a fool
Edit: re: Gandalf's example
code:
String fool = "Bobo".substring(0, 3);
The above line likely gets interpreted during optimization phase, and is compiled to fool = "Bob", which then in turn continues on as explained above.
Posted: Tue Oct 07, 2008 9:59 pm Post subject: RE:Doing if-and-else with String variables
Good catch Tony, I wasn't actually aware of that. Java can be frustrating at times
[Gandalf]
Posted: Tue Oct 07, 2008 10:06 pm Post subject: RE:Doing if-and-else with String variables
Indeed, in my defense that is what I was referring to. Both refer to the same location in memory, which is also why I mentioned memory management as being semi-important in understanding Strings, and also why both statements will be printed, with default compiler arguments.
Good catch Tony? Geeze, I was the one who pointed it out! Poor me, never getting the credit I deserve! I have an ego to maintain here.
Clayton
Posted: Tue Oct 07, 2008 10:11 pm Post subject: RE:Doing if-and-else with String variables
Your ego needs to be deflated anyways, not to mention I really didn't catch on at first, my apologies. Good catch Gonfalf.
Vermette
Posted: Thu Oct 09, 2008 8:01 pm Post subject: Re: Doing if-and-else with String variables
Bonus food for thought:
ans.equals("Ottawa") will throw a NullPointerException if ans is not initialized. You can get around this by calling the method on the nonnull string (and don't need/care about a null case):
Java:
"Ottawa".equals(ans)
HellblazerX
Posted: Thu Oct 09, 2008 8:52 pm Post subject: RE:Doing if-and-else with String variables
Well, this should make sense, seeing as .equals () isn't a static method, so it can only be called from an instance. Since ans is merely a reference w/o an instance attached to it, the NullPointerException is thrown. On the other hand, "Ottawa".equals (ans), your merely passing a null value in as the parameter.