4

As we know if we do a check like below the output will be equal.

String s1 = "stackoverflow";
String s2 = "stackoverflow";
if(s1==s2){
    System.out.println("equal");
}

So my question is if i am not using new operator in my application to create String and all are strings are literals so can i use only reference equality as given above? Thanks in advance.

N.B: i am writing a crawler so i need to check whether i have already visited the given url that i am currently holding. I am using murmur hash which gives me a long for every url but there are collision so i need to check for the content if the url string if there is a hash collision. Hence for performance i am thinking of just comparing the reference equality of two string urls. And i am using jsoup for html parsing.

Trying
  • 14,004
  • 9
  • 70
  • 110
  • 3
    If you're writing a recursive crawler, not all of your strings are literals. However, look at interning. – SLaks Dec 27 '13 at 13:31
  • 1
    If every string is a literal and you don't do any operations (substring, concatenation with unknown variables, etc) on it, then you should be able to just use `==`, yes. – Jeroen Vannevel Dec 27 '13 at 13:34
  • Please refer http://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java – user3119954 Dec 27 '13 at 13:42

3 Answers3

7

if i am not using new operator in my application to create String and all are strings are literals so can i use only reference equality as given above?

If you are 100% sure that all the strings you are dealing with are plain string literals or compile-time constant expressions then yes. The Java Language Specification §15.28 mandates that

Compile-time constant expressions of type String are always "interned" so as to share unique instances, using the method String.intern.

But if you get strings from anywhere else (e.g. reading them from a web page retrieved by your crawler, or building them using concatenation expressions that are not compile-time constants) then you must use .equals to compare them by value rather than by reference or .intern() them explicitly.

It's not always obvious whether an expression is a compile-time constant or not:

String s1 = "Stack";
String s2 = s1 + "Overflow"; // not a CTC

but

final String s1 = "Stack";
String s2 = s1 + "Overflow"; // _is_ a CTC, because s1 is a "constant variable"
                             // (final, with an initializer that is itself a CTC)
Ian Roberts
  • 120,891
  • 16
  • 170
  • 183
1

No, you cannot. The VM does not guarantee described behavior, it is an optimization. To guarantee this behavior, you need to call String#intern().

This and only this will guarantee reference equality.

But do a performance test, String#equals() is probably faster :-)

Jan
  • 1,042
  • 8
  • 22
1

So my question is if i am not using new operator in my application to create String and all are strings are literals so can i use only reference equality as given above?

Yes , for sure. Since they are resolved at compile time , so no issues.

But keep in mind the below scenario

       String s3= s2;
       String s4= s1+"";   //resolved at run time 
      System.out.println(s3==s4);  //false
      System.out.println(s3.equals(s4));//true

So until unless you are sure that the strings not going to be change later, you can safely use ==.

Suresh Atta
  • 120,458
  • 37
  • 198
  • 307