6

In Java, if one is to check if two Strings are equal, in the sense that their values are the same, he/she needs to use the equals method. E.g. :

String foo = "foo"; 
String bar = "bar";
if(foo.equals(bar)) { /* do stuff */ }

And if one wants to check for reference equality he needs to use the == operator on the two strings.

if( foo == bar ) { /* do stuff */ }

So my question is does the == operator have it's use for the String class ? Why would one want to compare String references ?

Edit: What I am not asking : How to compare strings ? How does the == work ? How does the equals method work?

What I am asking is what uses does the == operator have for String class in Java ? What is the justification of not overloading it, so that it does a deep comparison ?

Evdzhan Mustafa
  • 3,645
  • 1
  • 24
  • 40
  • 1
    Operator overloading in Java? It's a C++ concept, among many more languages, but not Java... – fps Feb 27 '15 at 23:14
  • There's nothing special about `String` (other than literals). It's a reference type like any other. – Sotirios Delimanolis Feb 27 '15 at 23:30
  • 1
    It is a reasonable question. Why are people downvoting? – Robert Jeppesen Feb 27 '15 at 23:34
  • @Hovercraft, *To change what `==` does for just one class, and make it behave differently from all other classes would break the `==` contract. It would be ludicrous to do.* Interestingly, that's exactly what C# does. – Frédéric Hamidi Mar 03 '15 at 13:44
  • 4
    @HovercraftFullOfEels _To change what `+` does for just one class, and make it behave differently from all other classes would break the `+` contract. It would be ludicrous to do._ :) – biziclop Mar 03 '15 at 13:58
  • 3
    @biziclop: point made, and I retract my comment. But I agree with your answer that this seems an arbitrary design decision, and so the question devolves into "what were the Java designers thinking at the time this decision was made" kind of question. – Hovercraft Full Of Eels Mar 03 '15 at 15:01
  • 1
    @HovercraftFullOfEels Yeah, more or less. James Gosling basically says in the linked interview that in his experience more developers were angry about the abuse of operator overloading than who were angered by the lack of them, so it was almost by popular vote that Java ended up with this solution. – biziclop Mar 03 '15 at 15:06

11 Answers11

15

Imagine a thread-safe Queue<String> acting as a communication channel between a producer thread and a consumer thread. It seems perfectly reasonable to use a special String to indicate termination.

// Deliberate use of `new` to make sure JVM does not re-use a cached "EOT".
private static final String EOT = new String("EOT");
...
// Signal we're done.
queue.put(EOT);


// Meanwhile at the consumer end of the queue.
String got = queue.get();
if ( got == EOT ) {
  // Tidy shutdown
}

note that this would be resilient to:

queue.put("EOT");

because "EOT" != EOT even though "EOT".equals(EOT) would be true.

OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213
10

What use is there for it? Not much in normal practice but you can always write a class that operates on intern()-ed strings, which can then use == to compare them.

Why it isn't overloaded is a simpler question: because there is no operator overloading in Java. (To mess things up a bit, the + operator IS sort of overloaded for strings, which was done to make string operations slightly less cumbersome. But you can argue that's just syntactic sugar and there certainly is no operator overloading in Java on the bytecode level.)

The lack of an overloaded == operator made the use of the operator much less ambiguous, at least for reference types. (That is, until the point autoboxing/unboxing was introduced, which muddies the waters again, but that's another story.) It also allows you to have classes like IdentityHashMap that will behave the same way for every object you put into it.

Having said all that, the decision to avoid operator overloading (where possible) was a fairly arbitrary design choice.

biziclop
  • 48,926
  • 12
  • 77
  • 104
  • "It also allows you to have classes like IdentityHashMap that will behave the same way for every object you put into it." - Point taken. Thanks. – Evdzhan Mustafa Mar 03 '15 at 16:18
0

The == operator compares the reference between two objects. For example, if String x and String y refers to two different things, then the == operator will show false. However, the String.equals() method compares not if they refer to each other, but if the values (ex. "Hello", "World", etc.) are the same.

Nolan Akash
  • 989
  • 8
  • 21
0
// A.java
String foo1 = "foo";
// B.java 
String bar1 = "foo";

All String literals realized at compile time are added to String Constant Pool. So when you have two different String declarations in two different classes, two String objects will not be created and both foo1 & bar1 refer to the same String instance of value foo. Now that you have same String reference in two different variables, you can just check if those two strings are equal just by using == which is fast because all it does is compare the bit pattern, where as in equals() method, each character is compared and is generally used for two different String instances but same content.

In fact, if you look at equals() implementation in String class, the first check they do is Reference comparison using == because they might seem as different instances to you, but if they're String literals or if they're interned by someone else already, then all you have is a Single reference in two variables.

  public boolean equals(Object anObject) {
      if (this == anObject) {
            return true;
      }
     // remaining code
  }

Also, == is not just for Strings, it's used to compare any two bit patterns, be it primitives or references

Arkantos
  • 6,530
  • 2
  • 16
  • 36
0

1."=="operation of comparison are the values of the two variables are equal, for a reference type variables is expressed by the two variables in the heap memory address is the same, namely the stack have the same content.

2."equals"Whether the two operation variables represent references to the same object in the heap, i.e. whether the contents of the same.

sundroid
  • 24
  • 3
0

String s = "string1"; creates 1 reference and 1 object in pool String s1 = "string1"; creates just 1 reference and points to what s is pointing to.

s == s1 // true

String s2 = new String("string1"); creates 1 object in heap, one in pool and one reference.

//Since, s2 is pointing to different object so, 
s2 == s // false
s1 == s // false

Problem : So, suppose We want to check, how many unique String object is created and stored in pool by the application while it is running,

We can have a singleton object which can have all the String references stored in an array.

From the previous examples of s, s1 and s2, finally for s and s1, 1 object is created and for s2, 1 object (in total 2).

//If we use equals method, all 

s.equals(s1) // gives true
s1.equals(s2) // gives true

//So, number of references present in the array of singleton object will be our 
//total number of objects created which equals to 3 // doesn't match actual 
//count which is 2

we can use == to check for equality of reference, so if reference is equal, we will not increment our count of unique String object in pool, and for every non equal result, we will increment the count.

here,

for

s // count = 1

s1 == s // count remains same

s2 == s // false, so count = 1 + 1 = 2

//We get total number of unique String objects created and got stored in pool using ==
Nielarshi
  • 1,126
  • 7
  • 11
0

Simple answer...

Why would one want to compare String references ?

Because they want to compare String values in a very fast way.

Strings are not always interned(). String constants are, but it is possible that the string was created manually on the heap. Using the intern() on a manually created string allows us to to continue using reference comparison on our strings for value comparison.

What is the justification of not overloading it, so that it does a deep comparison ?

  1. Because Java does not have operator overloading as a design decision
  2. Operator '==' is a reference operator always, and equals() is a value method always. In C++ you can change that, but many feel that simply obfuscates the code.
Community
  • 1
  • 1
kervin
  • 11,672
  • 5
  • 42
  • 59
  • Since the first thing `String.equals()` does is test for ==, speed is not a real issue here. Using == saves a function call, but after that, if the two Strings are ==, using `equals()` is just as fast. – user949300 Mar 09 '15 at 15:50
  • In some corner cases a function call is important. Think extremely tight, possibly nested loops. Secondly, you downvoted, but I'm not advocating the approach, just pointing out a valid use for == as the question asks. – kervin Mar 09 '15 at 18:05
0
  • Checking references is Faster compared to checking the entire Strings' equality.

    • Assume you have Large Strings (URLs or DBMS queries), a have multiple references to them. To check if they are equal, either you can check character by character or you can check if they both refer to the same object.
    • In fact, equals method in java first checks if the references are same and only if not goes ahead and checks character by character.

  • Java is full of references and hence, you might need a case where you need to check if two variables are referring to the same String/Object rather than both having each copy of the same String so that you can update string at one place and it reflects in all variables.
    • To do so, equals method does not help as it checks the copies to be equal as well. you need to check if they both refer to the same object and hence == comes into picture.
prasad vsv
  • 1,138
  • 8
  • 10
0

It seems that this was asked before and received quite a popular answer here:

Why didn't == operator string value comparison make it to Java?

The simple answer is: consistency

I guess it's just consistency, or "principle of least astonishment". String is an object, so it would be surprising if was treated differently than other objects.

Community
  • 1
  • 1
nadavge
  • 590
  • 1
  • 3
  • 14
0

Although this is not the fundamental reason, a usage could be to improve performances: before executing a heavy computation, "internalize" your Strings (intern()) and use only == for comparisons.

rom1v
  • 2,752
  • 3
  • 21
  • 47
0

What I am asking is what uses does the == operator have for String class in Java ? What is the justification of not overloading it, so that it does a deep comparison ?

== and equals have altogether different uses. == confirms if there is reference-equality Equals confirms if the objects contains are same.

Example of reference-equality is IdentityHashMap. There could be a case in which Only the object inserting something to IdentityHashMap has the right to get/remove the object.

overloading reference-equality can lead to unwanted complexity for java. for example if (string) { do deep equality } else { do reference-equality }

/*****************************************************************/

public class IdentityHashMap extends AbstractMap implements Map, Serializable, Cloneable

This class implements the Map interface with a hash table, using reference-equality in place of object-equality when comparing keys (and values). In other words, in an IdentityHashMap, two keys k1 and k2 are considered equal if and only if (k1==k2). (In normal Map implementations (like HashMap) two keys k1 and k2 are considered equal if and only if (k1==null ? k2==null : k1.equals(k2)).)

This class is not a general-purpose Map implementation! While this class implements the Map interface, it intentionally violates Map's general contract, which mandates the use of the equals method when comparing objects. This class is designed for use only in the rare cases wherein reference-equality semantics are required.