Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the equals method in String not use hash?

The code of the equals method in class String is

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; } 

I have a question - why does this method not use hashCode() ?

As far as I know, hashCode() can compare two strings rapidly.

UPDATE: I know, that two unequal strings, can have same hashes. But two equal strings have equal hashes. So, by using hashCode(), we can immediately see that two strings are unequal.

I'm simply thinking that using hashCode() can be a good filter in equals.

UPDATE 2: Here some code, about we are talking here.

It is an example how String method equals can look like

public boolean equals(Object anObject) {     if (this == anObject) {         return true;     }     if (anObject instanceof String) {         String anotherString = (String)anObject;         if (hashCode() == anotherString.hashCode()){             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;             }         }else{             return false;         }     }     return false; } 
like image 380
Mary Ryllo Avatar asked Jan 10 '13 16:01

Mary Ryllo


People also ask

What does the equals () method do in strings?

Java String equals() Method The equals() method compares two strings, and returns true if the strings are equal, and false if not. Tip: Use the compareTo() method to compare two strings lexicographically.

Should equals use hashCode?

Java hashCode() An object hash code value can change in multiple executions of the same application. If two objects are equal according to equals() method, then their hash code must be same.

Do equal strings have the same hashCode?

Two same strings/value must have the same hashcode, but the converse is not true. There might be another string which can match the same hash-code, so we can't derive the key using hash-code. The reason for two different string to have the same hash-code is due to the collision.

Does equals use hashCode java?

Java hashCode() and equals() method are used in Hash table based implementations in java for storing and retrieving data.


2 Answers

Hashcode could be a first-round check for inequality. However, it presents some tradeoffs.

  1. String hashcodes are lazily calculated, although they do use a "guard" value. If you're comparing strings with long lifetimes (ie, they're likely to have had the hashcode computed), this isn't a problem. Otherwise, you're stuck with either computing the hashcode (potentially expensive) or ignoring the check when the hashcode hasn't been computed yet. If you have a lot of short-lived strings, you'll be ignoring the check more often than you'll be using it.
  2. In the real world, most strings differ in their first few characters, so you won't save much by checking hashcode first. There are, of course, exceptions (such as URLs), but again, in real world programming they occur infrequently.
like image 58
parsifal Avatar answered Oct 08 '22 00:10

parsifal


This question has actually been considered by the developers of the JDK. I could not find in the various messages why it has not been included. The enhancement is also listed in the bug database.

Namely, one of the proposed change is:

public boolean equals(Object anObject) {     if (this == anObject) // 1st check identitiy         return true;     if (anObject instanceof String) { // 2nd check type         String anotherString = (String)anObject;         int n = count;         if (n == anotherString.count) { // 3rd check lengths             if (n != 0) { // 4th avoid loading registers from members if length == 0                 int h1 = hash, h2 = anotherString.hash;                 if (h1 != 0 && h2 != 0 && h1 != h2) // 5th check the hashes                     return false; 

There was also a discussion to use == for interned strings (i.e. if both strings are interned: if (this != anotherString) return false;).

like image 30
assylias Avatar answered Oct 08 '22 00:10

assylias