Why is String equals not working in my code? - java

I have already checked two compared strings, but even the value parameter str and temp is printed both "mn". The str.equals(temp) is still returning false.
public int strStr(String haystack, String needle) {
StringBuffer str=new StringBuffer(needle);
int result=-1;
for(int i=0;i<=haystack.length()-needle.length();i++){
StringBuffer temp = new StringBuffer(haystack.substring(i, i+needle.length()));
System.out.println(temp.equals(str));
System.out.println(temp+"="+str);
if (str.equals(temp)){
result=i;
break;
}
}
return result;
}

You are comparing two StringBuffer objects. The equals(Object) method for StringBuffer is inherited from Object, and is defined to be the same as comparing the object references.
The objects are different, and therefore, the result is false in your example.
Try this instead:
if (str.toString().equals(temp.toString())){
This works because the String.equals(Object) compares the string values, not the string object references. (But note that you have to convert both StringBuffer objects, because String.equals(Object) will always return false if the argument is not a String object.)
Note also that using str as the name for a StringBuffer variable is highly misleading. Most people would expect something called str to be a String. (I did!!)
FWIW, I was scratching my head for a more efficient way to compare the contents of two StringBuffer objects. The above code creates and discards two temporary String objects. The best I can come up with is to code it by hand; e.g. something like this:
public boolean equalBuffers(StringBuffer sb1, StringBuffer sb2) {
if (sb1 == sb2) {
return true;
}
int len = sb1.length();
if (len != sb2.length()) {
return false;
}
for (int i = 0; i < len; i++) {
if (sb1.charAt(i) != sb2.charAt(i)) {
return false;
}
}
return true;
}

You are comparing the references to the StringBuffer objects rather than the actual strings.And
StringBuffer class doesn't override the equals() method of Object class.
Try this
str.toString().equals(temp.toString())
The java.lang.StringBuffer.toString() method returns a string representing the data in this sequence.
A new String object is allocated and initialized to contain the character sequence currently represented by this object. This String is then returned.
thats why you can compare two StringBuffer object by converting them into string.

You are comparing StringBuffer with String so the equals method always return false.
str.equals(temp.toString())
But you need to know another important concept here when you does
System.out.println(temp+"="+str);
you are printing temp which is stringbuilder, java internally calls temp.toString() to achieve this.

Related

Arrays comparation in java [duplicate]

int [] nir1 = new int [2];
nir1[1] = 1;
nir1[0] = 0;
int [] nir2 = new int [2];
nir2[1] = 1;
nir2[0] = 0;
boolean t = nir1.equals(nir2);
boolean m = nir1.toString().equals(nir2.toString());
Why are both m and t false? What is the correct way to compare 2 arrays in Java?
Use Arrays.equals method. Example:
boolean b = Arrays.equals(nir1, nir2); //prints true in this case
The reason t returns false is because arrays use the methods available to an Object. Since this is using Object#equals(), it returns false because nir1 and nir2 are not the same object.
In the case of m, the same idea holds. Object#toString() prints out an object identifier. In my case when I printed them out and checked them, the result was
nir1 = [I#3e25a5
nir2 = [I#19821f
Which are, of course, not the same.
CoolBeans is correct; use the static Arrays.equals() method to compare them.
Use Arrays.equals instead of array1.equals(array2). Arrays.equals(array1, array2) will check the content of the two arrays and the later will check the reference. array1.equals(array2) simply means array1 == array2 which is not true in this case.
public static boolean perm (String s, String t){
if (s.length() != t.length()) {
return false;
}
char[] perm1 = s.toCharArray();
Arrays.sort(perm1);
char[] perm2 = t.toCharArray();
Arrays.sort(perm2);
return Arrays.equals(perm1, perm2);
}
boolean t = Arrays.equals(nir1,nir2)
I just wanted to point out the reason this is failing:
arrays are not Objects, they are primitive types.
When you print nir1.toString(), you get a java identifier of nir1 in textual form. Since nir1 and nir2 were allocated seperately, they are unique and this will produce different values for toString().
The two arrays are also not equal for the same reason. They are separate variables, even if they have the same content.
Like suggested by other posters, the way to go is by using the Arrays class:
Arrays.toString(nir1);
and
Arrays.deepToString(nir1);
for complex arrays.
Also, for equality:
Arrays.equals(nir1,nir2);
Use this:
return Arrays.equals(perm1, perm2)
Instead of this:
return perm1.equals(perm2);
Please have to look this

Java string comparison not working as intended

I've done quite a bit of string comparisons in java in the past, but this time it doesn't seem to work.
I'm aware of the fact, that you have to use the .equals() function in order to compare strings in java.
In my attempt to figure out what's wrong, I wrote the following code snippet: Log.e("testLogic", String.valueOf(taken.getText().toString().trim().equals('1')));
Log.e("testValue", taken.getText().toString().trim());
producing the following result:
E/testLogic﹕ false
E/testValue﹕ 1
E/testLogic﹕ false
E/testValue﹕ 1
E/testLogic﹕ false
E/testValue﹕ 0
This seems rather strange, since the two first 'testLogic' logs should produce true.
The code is used in a custom list adapter if it means anything.
/Mikkel
It is because you are not comparing 2 Strings. You have to put it like this:
Log.e("testLogic", String.valueOf(taken.getText().toString().trim().equals("1")));
because .equals() function needs two Strings. Supposing that s1 and s2 are Strings, you should do:
s1.equals(s2);
I expect it will be helpful for you!
The .equals() comes from the Object class. Each class inherit it from the Object class. String class also inherited it from the Object class and override it like this -
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
And String has not any overloaded version of equals method for char. You can see if String's .equals() method takes any object but it returns false when it is any type rather than String. It only returns true if the provided parameter is of type String and is meaningfully equals. So you have to write -
Log.e("testLogic",String.valueOf(taken.getText().toString().trim().equals("1")));
instead of -
Log.e("testLogic", String.valueOf(taken.getText().toString().trim().equals('1')));

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.

What is an efficient way to compare StringBuilder objects

Well I have two StringBuilder objects, I need to compare them in Java.
One way I know I can do is
sb1.toString().equals(sb2.toString());
but that means I am creating two String objects, is there any better way to compare StringBuilder objects. Probably something where you do not need to create additional objects?
As you apparently already know, StringBuilder inherits equals() from java.lang.Object, and as such StringBuilder.equals() returns true only when passed the same object as an argument. It does not compare the contents of two StringBuilders!
If you look at the source, you'll conclude that the most efficient comparison (that didn't involve creating any new objects) would be to compare .length() return values, and then if they're the same, compare the return values of charAt(i) for each character.
Since Java 11, StringBuilder implements Comparable, so you can use a compareTo method for the equality test:
System.out.println(sb1.compareTo(sb2) == 0);
Two StringBuilder objects are never equal. Use .toString() to get the string representation for both the objects and then use .equals() to compare the objects. This way equals() method from the String class gets invoked that compares the string value of the objects instead of comparing the memory location.
StringBuilder a= new StringBuilder("HELLO JAVA");
StringBuilder b= new StringBuilder("HELLO JAVA");
if (a.toString().equals(b.toString())){
System.out.println("Objects are equal");
}
A solution without new allocations would be to compare first at length, and if it differs, then char by char. This is more efficient and faster than performing a compare via a toString() on the StringBuilder call, which would allocate a new string.
The next snipped assumes both parameters aren't null neither the same object instance:
public boolean compare(final StringBuilder left, final StringBuilder right) {
final int length = left.length();
if (length != right.length())
return false;
for (int index = 0; index < length; index++) {
if (left.charAt(index) != right.charAt(index))
return false;
}
return true;
}

Difference between String#equals and String#contentEquals methods

What is the difference between the String#equals method and the String#contentEquals method?
The String#equals() not only compares the String's contents, but also checks if the other object is also an instance of a String. The String#contentEquals() only compares the contents (the character sequence) and does not check if the other object is also an instance of String. It can be anything as long as it is an implementation of CharSequence which covers a.o. String, StringBuilder, StringBuffer, CharBuffer, etc.
To put it easily: String.contentEquals() is the smarter brother of String.equals(), because it can be more free in the implementation than String.equals().
There are some reasons why there is a separate String.contentEquals() method. The most important reason I think is:
The equals method has to be reflexive. That means that: x.equals(y) == y.equals(x). This implies that aString.equals(aStringBuffer) would have to be the same as aStringBuffer.equals(aString). This would require the Java API developers to make some special implementation for Strings in the equals() method of StringBuffer, StringBuilder and CharSequence as well. This would be a mess.
This is where String.contentEquals comes in. This is a standalone method that does not have to follow the strict requirements and rules for Object.equals. This way, you can implement the sense of "equal content" more freely. This allows you to make intelligent comparisons between a StringBuffer and a String, for example.
And to say what exactly the difference is:
String.contentEquals() can compare the contents of a String, a StringBuilder, a StringBuffer, a CharSequence and all derived classes of these. If the parameter is of type String, then String.equals() get executed.
String.equals() only compares String objects. All other object types are considered as not equal.
String.contentEquals() can compare StringBuffer and StringBuilder in an intelligent way. It does not call the heavy toString() method, which copies the whole content to a new String object. Instead, it compares with the underlying char[] array, which is great.
This answer was already posted by dbw but he deleted it but he had some very valid points for the difference while comparing execution time, what exceptions are thrown,
If you look at the source code String#equals and String#contentEquals it is clear that there are two overridden methods for String#contentEquals one which take StringBuilder and other CharSequence.
The difference between them,
String#contentEquals will throw NPE if the argument supplied is null but String#equals will return false
String#equals compares the content only when the argument supplied is instance of String otherwise it will return false in all other cases but on the other hand String#contentEquals checks the content of all the objects which implement interface CharSequence.
You can also tweak the code so that String#contentEquals return the wrong result or result you want by overriding equals method of the argument passed as shown below but you can not do those tweaks with String#equals.
Below code will always produce true as long as s contains any string which is 3 character long
String s= new String("abc");// "abc";
System.out.println(s.contentEquals(new CharSequence()
{
#Override
public CharSequence subSequence(int arg0, int arg1) {
// TODO Auto-generated method stub
return null;
}
#Override
public int length() {
// TODO Auto-generated method stub
return 0;
}
#Override
public char charAt(int arg0) {
// TODO Auto-generated method stub
return 0;
}
#Override
public boolean equals(Object obj)
{
return true;
}
}));
String#contentEquals will be slower then String#Equals in the case when argument supplied is instance of String and the length of both String is same but contents are not equal.
Example if the string are String s = "madam" and String argPassed = "madan" then s.contentEquals(argPassed) will take almost double execution time in this case as compared to s.equals(argPassed)
If the content length are not same for both the strings then function String#contentEquals will have better performance then String#Equals in almost all possible cases.
One more point to add to his answer
String#contentEquals of a String object will also compare to the StringBuilder contents and provide the appropriate result while String#Equals will return false
String class equals(Object o) method does only String comparison. But contentEquals(CharSequence cs) checks for classes extends AbstractStringBuilder i.e. StringBuffer, StringBuilder and String class also (They all are of type CharSequence).
String str = "stackoverflow";
StringBuilder builder = new StringBuilder(str);
System.out.println(str.equals(builder));
System.out.println(str.contentEquals(builder));
output:
false
true
The output of first stmt is false because builder is not of type String so equals() returns false but the contentEquals() checks for the content of all the type like StringBuilder, StringBuffer, String and as the content is same hence true.
contentEquals will throw NullPointerException if the argument supplied is null but equals() will return false because the equals() checks for instanceOf ( if (anObject instance of String) ) which returns false if the argument is null.
contentEquals(CharSequence cs):
Lets you check equality of given string value with any implementation instance of interface java.lang.CharacterSequence (eg, CharBuffer, Segment, String, StringBuffer, StringBuilder )
equals(Object anObject):
Lets you check equality of given string value with any instance of type java.lang.String only
RTFC :)
Since reading the source is the best way to understand it, I am sharing the implementations of both the methods (as of jdk 1.7.0_45)
public boolean contentEquals(CharSequence cs) {
if (value.length != cs.length())
return false;
// Argument is a StringBuffer, StringBuilder
if (cs instanceof AbstractStringBuilder) {
char v1[] = value;
char v2[] = ((AbstractStringBuilder) cs).getValue();
int i = 0;
int n = value.length;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
// Argument is a String
if (cs.equals(this))
return true;
// Argument is a generic CharSequence
char v1[] = value;
int i = 0;
int n = value.length;
while (n-- != 0) {
if (v1[i] != cs.charAt(i))
return false;
i++;
}
return true;
}
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
There is another method of String#contentEquals():
public boolean contentEquals(StringBuffer sb) {
synchronized(sb) {
return contentEquals((CharSequence)sb);
}
}
equals() and contentEquals() are two methods in String class to compare two strings and string with StringBuffer.
The parameters of contentEquals() are StringBuffer and String(charSequence). equals() is used to compare two strings and contentEquals() is used to compare the contents of String and StringBuffer.
Method contentEquals and equals are
public boolean contentEquals(java.lang.StringBuffer);
public boolean contentEquals(java.lang.CharSequence);
public boolean equals(Object o)
Here is an code which describes both methods
public class compareString {
public static void main(String[] args) {
String str1 = "hello";
String str2 = "hello";
StringBuffer sb1 = new StringBuffer("hello");
StringBuffer sb2 = new StringBuffer("world");
boolean result1 = str1.equals(str2); // works nice and returns true
System.out.println(" str1.equals(str2) - "+ result1);
boolean result2 = str1.equals(sb1); // works nice and returns false
System.out.println(" str1.equals(sb1) - "+ result2);
boolean result3 = str1.contentEquals(sb1); // works nice and returns true
System.out.println(" str1.contentEquals(sb1) - "+ result3);
boolean result4 = str1.contentEquals(sb2); // works nice and returns false
System.out.println(" str1.contentEquals(sb2) - "+ result4);
boolean result5 = str1.contentEquals(str2); // works nice and returns true
System.out.println(" str1.contentEquals(str2) - "+ result5);
}
}
Output:
str1.equals(str2) - true
str1.equals(sb1) - false
str1.contentEquals(sb1) - true
str1.contentEquals(sb2) - false
str1.contentEquals(str2) - true
The contentEquals() method checks is the contents are same between a String, StringBuffer, etc which some kind of char sequence.
String#equals takes Object as an argument and checks it is instance of String object or not. If the argument object is String Object then it compares content character by character. It returns true in case content of both string objects are same.
String#contentEquals takes CharSequence interface as an argument. CharSequence can be implements in 2 ways-by using i) String class or (ii) AbstractStringBuilder( parent class of StringBuffer, StringBuilder)
In contentEquals() length is compared before any object instance check. If length is same then it checks argument object is instance of AbstractStringBuilder or not. If it is so(i.e. StringBuffer or StringBuilder ) then content is checked character by character. In case argument is an instance of String object then String#equals called from String#contentEquals.
So in short,
String#equals compares the content character by character in case argument is String object also. And String#contentEquals compares the content in case argument object implement CharSequence interface.
String#contentEquals is slower in case we compare two same length string content as String#contentEquals internally calls String#equals for String object.
In case we try to compare objects with difference content length (say "abc" with "abcd") then String#contentEquals is faster than String#equals. Because length is compared before any object instance checking.
BTW, the historical reason for the difference is that String originally had no superclass, so String.equals() takes a String as its argument. When CharSequence was introduced as the superclass of String, it needed an equality test of its own that worked across all CharSequence implementations, and that would not collide with the equals() already in use by String... so we got CharSequence.contentEquals(), which is inherited by String.
If CharSequence has been present in Java 1.0, we would probalby have only CharSequence.equals() and String would simply implement that.
Ah, the joys of evolving languages...

Categories