Error for String Comparison in Java [duplicate] - java

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 7 years ago.
I have this
public void otis() {
println("What is Otis?");
String otis = readLine(">");
println("You said " + otis);
println(otis);
println(otis);
if (otis == "dog"){
println("you got it right!");
}
else {
println("try it again!");
otis();
}
}
But for some reason even when I respond "dog" it doesn't find a match. I can print the "otis" variable and it says "dog" but apparently that's not equivalent to "dog" somehow?

Can you try the code below? Java doesn't recognize strings as equivalent from two different instantiations even if their values are equivalent. This is because each string is a pointer, and their pointer values aren't equivalent. Try using the String.equal method!
otis.equals( "dog" )

Because == means "is the same exact object in memory", the constant string "dog" and the string it reads from the console are not the same object, even if they have the same contents. When doing comparisons in Java, always use .equals().
As a possible side effect of this, you have to be careful when comparing things that might be null in Java. If you try to do
String dog = null;
if(dog.equals("dog")) { do_something(); }
You'll end up with a NullPointerException. For this reason, many coders prefer to compare strings like this:
if("dog".equals(dog)) { do_something(); }
since you always know the constant string will not be null.

Related

Why the order is reverse in equals() [duplicate]

This question already has answers here:
String.equals() argument ordering
(10 answers)
Closed 3 years ago.
In part of the code for check empty string the programmer use equals() like this:
if ("".equals(name)) {
// some logic
}
Why is it executed from a string value directly? What is the difference from this;
if (name.equals("")) {
// some logic
}
Both of them have the same result, but what is the idea behind doing the first one?
The idea behind using;
"".equals(name)
is that "" can never be null, whereas name can be. equals() accepts null as a parameter, but trying to execute a method from a null variable will result in a NullPointerException.
So this is a shorthand way to evade such possible exceptions. Same goes for any such constant object.
e.g.
final Integer CONSTANT_RATE = 123456;
....
if (CONSTANT_RATE.equals(someVariable)) { .. }
rather than doing;
if (someVariable != null && someVariable.equals(CONSTANT_RATE)) { .. }

can someone explain why this returns the "else" value and not the "then" value? [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 4 years ago.
the java subSequence is clearly true but only returns the false value. why?
trying to see if a sequence is equal to a subsequence of a bigger string
package testifthen;
public class TestIfThen {
public static void main(String[] args) {
String result = "01900287491234567489";
String result1 = "90028749";
if (result.subSequence(2, 10) == result1) {
System.out.println("excel");
}else {
System.out.println("not found");
}
}}
It's hard to say without more information (for example what language is this in).
Assuming this is Java, I would say your problem is using == with strings instead of the .equals function.
== doesn't check the contents of the string, only if they are referencing the same object. .equals should be used instead as it actually checks whether the characters match in the two strings
Try using
if (result.subSequence(2, 10).equals(result1)) {
System.out.println("excel");
} else {
System.out.println("not found");
}
The == symbol might be the one causing it to return false because of the different references.
This post should explain more about differences between == and equals(): What is the difference between == vs equals() in Java?
In Java, the .equals method should be preferred to the == operator when checking for semantic equality. .equals should be used when you are checking if two values "mean" the same thing, whereas == checks if they're the same exact object.

Java: Converting Integer to String. Comparing with == equals operator [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 8 years ago.
public static void main(String[] args) {
Integer i = new Integer(4);
System.out.println(i.toString());
if (i.toString() == i.toString()) {
System.out.println("true how");
} else {
System.out.println("false how");
}
}
While executing above code, I am getting output as "false how".
Can you explain how Jvm treats this object?
toString() creates a new string object every time and your code is actually checking if both references are the same, which is never the case so it runs the else case. If you try
i.toString().equals(i.toString())
you'll get the desired output.
You must compare objects with equals() method.
i.toString().equals(i.toString())

Java Input Problems - how to compare strings [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 7 years ago.
This seems to be pretty simple, but I have been stucked here for a couple of hours.
I have a doubt when you have to compare two Strings in Java.
if I just do something like this:
String var1 = "hello";
String var2 = "hello";
and then compare these two words in another function, the result will clearly be true.
But the problem is when I have to compare two words that come from an input. Here is my code:
import java.util.Scanner;
public class Compare{
public static void main(String[] args){
Scanner Scanner = new Scanner (System.in);
System.out.println("Enter first word: ");
String var1 = Scanner.nextLine();
System.out.println("Enter second word: ");
String var2 = Scanner.nextLine();
if (same (var1, var2))
System.out.println("Yes");
else
System.out.println("No");
}
public static boolean same (String var1, String var2){
if (var1 == var2)
return true;
else
return false;
}
}
I have tried several times (clearly entering the same word) and the result is always False.
I don't know why this happens. What am I missing?
This is my first time in Java. I will appreciate any kind of help. Thanks
You should change
if (var1 == var2)
{
return true;
}
else
{
return false;
}
to
if (var1.equals(var2))
{
return true;
}
else
{
return false;
}
See this answer for the difference between the two
To be more accurate, with Strings in Java sometimes you can use == instead of .equals, if your string has been interned. Remember that == always compares the object references, not the contents of the object. Interning a String means that you will get the same object reference back and this is why == works with interned Strings.
Please read the Javadoc here to understand this more clearly:
String.intern()
In Java the == is a reference equality operator.
It works with the following.
String var1 = "hello";
String var2 = "hello";
boolean cmp = var1 == var2;
just because they are string literals and they are allocated in the same place inside the string table, so both variables point to the same string.
If you are fetching data from another source the strings are dynamically allocated, hence you should use the var1.equals(var2) (and you should ALWAYS use that one when comparing two objects).
Instead of if (same (var1, var2)) use if (v1.equals(v2)). No need to create a new method to compare two Strings. That's what equals() does.
== is used to compares references, not the contents of each String object.
The equality operator(==) checks the refernce of string first then checks value of string.
While equals method checks the value first.
So,in this case equals method should be used instead of equality operator.
String s="hello";
String s1="hello";
String s3=new String("hello")
In the above code snippet if you use If(s==s1){System.out.print("Equal");}it would print equal.But if you check If(s==s3){System.out.print("unqual");}it wouldn't print unequal.
so,you can see that even strings s and s3 are equal,output is wrong.Therefore,in this scenario like program in question
Equals method must be used.
var1 == var2
sometimes works because VM allocates the same memory both the variables for memory optimization and thus having same reference. That cannot be always the case so it's better to use
var1.equals(var2)
If you want to compare their values and doesnt care about reference.

How does object.equals method is supposed to work in Java?

This is my source code. I'trying to implement a simple program that asks a question to a user and expects the answer to be "yes" or "no" and terminates only if the user answer to the question "yes" or "no". The book I have suggested me not to use == comparison and to use the equals method instead, so that the program can understand if the user typed "y e s" instead of "yes". But in this way the result is the same and the method seems to compare the user's answer if it is exactly "yes" or "no". It doesn't accept for example an aswer of "n o". Is that logical for that method? Is it supposed to work that way? How can I change the program to accept answers like "Yes" "ye s" "No" "NO" etc.? I would appreciate your help:)
import acm.program.*;
public class YesNoExample extends ConsoleProgram{
public void run(){
while(true){
String answer = readLine("Would you like instructions? ");
if(askYesNoQuestion(answer)){
break;
}
println("Please answer yes or no.");
}
}
private boolean askYesNoQuestion(String str){
if(str.equals("yes")||str.equals("no")){
return true;
}else{
return false;
}
}
}
If you use == you'll be comparing the references (memory pointers) of two String objects. If you use equals, a custom made method in the String class will be run that does some "intelligent" comparison, in this case, check that the characters are all the same, and the whole thing has the same length.
If you'd like to support mixed case letters, you could use "someString".equalsIgnoreCase("SoMeString") (which will return true). This is done (said roughly) by making both strings lowercase (so the case doesn't matter) and comparing them using equals.
Edit: The other posters made me realize that, in addition to capitalization, you also want to look for String equality where spaces don't matter. If that's the case, a similar trick to turning everything to lowercase applies, where you first remove all the spaces, as #LouisWasserman says in his answer
If you need to fuzzily identify yes/no, first you need exact rules as to what matches. Based on your examples, I can suggest this:
private boolean askYesNoQuestion(String str) {
str = str.replace(" ", "").toUpperCase();
return str.equals("YES") || str.equals("NO");
}
If interested in top performance and not at all in intelligibility, use this:
private static final Pattern p =
Pattern.compile("y\\s*e\\s*s|n\\s*o", Pattern.CASE_INSENSITIVE);
private boolean askYesNoQuestion(String str) {
return p != null && p.matcher(str.trim()).matches();
}
Semantics of == vs .equals()
First off you misunderstand the semantics.
== tests for object identity. A == B says is A a reference to the exact same object as B.
.equals() applies custom logic to test if the objects are equal in some logical manner, without being the exact same object. For this to be implemented correct, both objects should have the same .hashCode() value as well.
Idiomatic Java Solution
Since the String object is final which means it can't be inherited from. You can't override the .equals() on the String object.
What you need to do is preprocess the input into something that can be directly compared to the target value with .equalsIgnoreCase().
One way to do this is use, answer.replaceAll("\\s","") to remove all the whitespace then you can compare it to your target String literal with .equalsIgnoreCase().
A better method to replace askYesNoQuestion() would be:
private boolean isAnswerYesOrNo(final String answer)
{
final String input = answer.replaceAll("\\s","");
return "yes".equalsIgnoreCase(input) || "no".equalsIgnoreCase(input);
}
Comparing a literal to the input parameter will insulate you from NullPointerExceptions if the input parameter happens to be null "yes".equalsIgnoreCase()can never throw aNullPointerException`. This is idiomatic Java.
Get a better book
That book isn't very useful if it really says what you are claiming it says. Also it is teaching you to write lots of code to handle bad input when that is a complete anti-pattern and a well designed program would exit with a verbose explanation of the exact problem was what can be done to fix the input.
With the explanation of == and .equals well described above, here's a two examples of a one liner that does the comparison you want.
if ( Pattern.matches("\\s*[yY]\\s*[eE]\\s*[sS]\\s*", input) ) {
// do something
}
if ( input.replaceAll("\\s", "").equalsIgnoreCase("yes") ) {
// do something
}

Categories