-1
Here what is written in String API for Hashcode------
public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }

Can anybody explain how caching is happening here ?

One clue is :---- if (h == 0 && value.length > 0) { Code will only go inside this condition ,only then hashcode is calculated otherwise same is written.But how this happens for two string created with new like :

String a = new String("abc"); String b = new String("abc"); Please explain it

user3907559
  • 85
  • 1
  • 4

2 Answers2

4

But how this happens for two string created with new like :

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

It doesn't happen. Caching only occurs for a single String object.

 int h = hash;
 if (h == 0 && value.length > 0) {
        char val[] = value;

        for (int i = 0; i < value.length; i++) {
            h = 31 * h + val[i];
        }
        hash = h;
 }

For a single String, hash is where the hash code is stored. If it's 0, then it recomputes it -- storing it in the local variable h -- and once the hash code is newly computed, it's stored back in hash so it can be used in the future.

If Strings were mutable, then the stored hash code would be wrong after the string got changed, so any way of changing the string would have to reset hash to 0 to indicate it had to be recomputed anew. That gets messy, though, on many many different levels, which is why String is not mutable.

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
  • Would u please explain how it happens for a single string object and why it does not happen in case string is mutable – user3907559 Jan 12 '16 at 19:28
  • @user3907559 `String` is *never* mutable. – Andreas Jan 12 '16 at 19:30
  • Just assume if string is mutable ,then what are the consequences on caching – user3907559 Jan 12 '16 at 19:31
  • @user3907559 Can't assume that, because code was written to handle immutable only, so code would fail if it was mutable. Assuming otherwise is therefore meaningless. – Andreas Jan 12 '16 at 19:33
  • @user3907559 Then you'd have clear the cached hash value if the string was modified, so the hash is re-computed the next time you need it. – nos Jan 12 '16 at 19:33
  • Thanks Louis ,But can you give some or one example where it get messy if string is mutable.Actually this question has been asked in interview .So Please do this favour – user3907559 Jan 12 '16 at 19:34
  • @user3907559 I won't answer that myself; that's been answered many other times elsewhere on StackOverflow, e.g. http://stackoverflow.com/q/22397861/869736 – Louis Wasserman Jan 12 '16 at 19:35
  • From your link ,can u please provide me example where security issues are cropping up if string is mutable? lets say u take example of databases – user3907559 Jan 12 '16 at 19:41
  • @user3907559 Let's say I connect to the database and send a `String` saying my username is `"randomuser"`. Then after I've got a connection to the database and logged in with my `randomuser` password, I change the `String` with my username to say `"admin"`. That bad. – Louis Wasserman Jan 12 '16 at 19:42
3

Each string object has a field called "hash". whenever hashcode() is called on string object, a local variable int h is declared with initial value of "hash" field. As initially hash value will be zero, hash value of this string is computed and stored in hash field. Henceforth whenever hashcode() is called on this string "hash" field value will be returned because it will be non-zero value and therefore not enter the if condition.

As String is immutable, hash value can be cached. If it is mutable, then this caching strategy will not work.

As your creating the two Strings using new, both will be different instances, and therefore each will have their own hash fields.

public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];

/** Cache the hash code for the string */
private int hash; // Default to 0
...
public int hashCode() {
    int h = hash;
    if (h == 0 && value.length > 0) {
        char val[] = value;

        for (int i = 0; i < value.length; i++) {
            h = 31 * h + val[i];
        }
        hash = h;
    }
    return h;
}
}
prem kumar
  • 5,641
  • 3
  • 24
  • 36