简体   繁体   中英

String equality check in java

The difference between the following two statements:

  1. String s = "Hello";
  2. String s = new String("Hello');

In the first statement, assignment operator-is used to assign the string literal to the String variable s . In this case; JVM first of all checks whether the same object is already available in the string constant pool. If it is available, then it creates another reference to it. If the same object is not available, then it creates another object with the content "Hello" and stores it into the string constant pool.

In the second statement, new operator is used to create the string object. In this case, JVM always creates a new object without looking in the string constant pool.

The doubt I am having from the code which I have provided below is the output of statement

System.out.println(a.hashCode() + " " + b.hashCode());

Here both the object should have different memory location according to the rules, but hashcode for both of them is showing true

import java.util.HashMap;
import java.util.Map;

class TestStringEquality 
{ 
public static void main (String[] args) 
{ 

    String a = new String("abcd");
    String b = new String("abcd");

    System.out.println(a == b);
    System.out.println(a.hashCode() + " " + b.hashCode());
    System.out.println(a.equals(b));

    Map<String, String> map = new HashMap<>();

    map.put(new String("abcd"), "abcd");
    map.put(new String("abcd"), "wxyz");


    System.out.println(map);
} 
}

The output what i am getting is as follows:

false
2987074 2987074
true
{abcd=wxyz}

According to the API sheet at https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#hashCode-- the formula used in hashcode of a String is dependent on the length and content of the String, not the memory location. Therefore two identical Strings with different memory locations should give the same hashcode.

Java has one concept named String Pool . Every string has used in the program will be stored in the pool as the cache mechanism.

For example below code:

String a = "StackOverFlow";  // Java will push StackOverFlow into string pool
String b = "StackOverFlow";  // Java will get address of "StackOverFlow" object in string pool and assigned to b.

In Java, programmers don't have to directly work with pointers. However, pointers still are here. When using the operator "==", primitive data-type variables like int, short … will compare by their values. But in String, Java will compare by their addresses.

That is the reason the following line will return true:

System.out.println(a == b); // true

However, when you call new String(...) , Java will create a new string object. It doesn't look into String Pool to check that string's value has stored in String Pool or not. That is the reason two variables have the same value, they are still different in address so "==" operator will return false.

String a = "StackOverFlow";
String b = new String("StackOverFlow"); // new string object. not use old one in String Pool.
System.out.println(a == b); // False. because they have different addresses. 

Because of String Pool mechanism, we must use equals method when compare two objects. By doing this, we don't need to care how that String object is built. So following code always return true:

String a = "StackOverFlow";
String b = "StackOverFlow";  // use same object as a
String c = new String("StackOverFlow"); // create new string
System.out.println(a.equals(b)); // true
System.out.println(a.equals(b)); // true
System.out.println(a.equals(c)); // true

About hashcode, Java will use a hash function to calculate the value from the string's characters. That way no matter how a string is built, if 2 strings are equal in value, they will have the same hash code.

String a = "StackOverFlow";
String b = "StackOverFlow";  // use same object as a
String c = new String("StackOverFlow"); // create new string
System.out.println(a.hashCode() == b.HashCode()); // true
System.out.println(a.hashCode() == c.HashCode()); // true

Based on the discussion, we can come to the following conclusion. If 2 strings have the same hash code, we cannot affirm operator "==" returns true. Because they might be the same value, but they are different objects on heap memory.

But the vice versa condition is correct. If 2 strings point to the same address, they will have the same value hence the same hash code.

Interesting question : If two strings have equal hash codes, can we assume those 2 strings will equal?

I think you are getting confused between normal heap memory and string constant pool. When you check for equals , JVM is fetching you the object stored in normal heap memory which is one and the same . They are different only in string constant pool. That's why '==' returns false as locations are different in string constant pool because the copies have different references but equals returns true since both are of same type and hold similar string.

hashCode() implementaiton of "Object" class returns underlying memory location.

hashCode() implementaiton of "String" overrides hashCode() in Object. Returns a hash code for this string. The hash code for a String object is computed as

s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]

Also, this makes programmers life easier. For example, we can query a Map using hard coded string key, instead of keeping the original key object with us.

this string equality you can use hashcode method. but, for better performance use

String firstString = "string1";
String secondString = "String1";
println(" it will return boolean " + firstString.equal(secondString ) + " "); //false
println(" it will return boolean " + firstString.equalIgnoreCase(secondString ) + " "); //true

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM