5

in Java when I say.

String str= "abcd";
str.hashCode(); 

My question is When is Hashcode calculated? @ line 1 or @ line 2?

I am assuming , that hashcode is pre-computed. Whenever string is updated hashcode would also 'perhaps' update.

or its the other way i.e. every time you call str.hashCode() java computes its using the formula that's described here.

Consistency of hashCode() on a Java string

Community
  • 1
  • 1
Arif Ali Saiyed
  • 657
  • 7
  • 11
  • Earlier , prior to reading the documentation, I was under wrong impression that 1) java.lang.String.hashCode() would never return same hashcode() for two String if both strings are not equals. 2) also I am still under impression that in java Strings hashcode are pre-computed . However documentation doesn't mention anything other than the formula which hints that its always computed, but dont want to assume. – Arif Ali Saiyed Jul 10 '13 at 11:47
  • Well, as you can see from the excerpt I posted, at least in the Sun JVM it's lazily calculated and cached. – Kayaman Jul 10 '13 at 12:00
  • You can't update existing `String` instance as [String is immutable](http://javarevisited.blogspot.com/2010/10/why-string-is-immutable-in-java.html). What you will be able to do is create a new instance and assign it to the same variable. – Ruchira Gayan Ranaweera Jul 10 '13 at 11:46

6 Answers6

9

Strings can't be updated since they're immutable, and the value is cached after it's computed once:

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;
    }
Kayaman
  • 72,141
  • 5
  • 83
  • 121
  • Its worth noting that (as far as im aware) hashcodes on mutable objects are also cashed and not recalculated on update – Richard Tingle Jul 10 '13 at 11:48
  • 1
    As with so many other things, this is an implementation specific detail of some Java VM. The hash code may be computed when the string instance is created, it may be computed for each invocation of `hashCode()` or it may be computed the first time `hashCode()` is invoked and cached for later usage. All three variants fulfill the requirements of the API contract. – jarnbjo Jul 10 '13 at 11:49
  • 5
    That would be reasonable. But as String is a very popular choice as a key for HashMap, it would be a significant oversight if it wasn't cached... – Kayaman Jul 10 '13 at 11:49
  • @jarnbjo Thanks. perhaps that the reason i dont find anything in the documentation. – Arif Ali Saiyed Jul 10 '13 at 11:58
  • I thought strings had fields which kept track of their offset and length, so as to expedite substring operations; were such fields omitted in later Java versions? What fields remain? – supercat Jul 12 '13 at 15:58
1

You cannot "update" a string. Strings are immutable. When you "change" a string instance, you actually get a new string instance.

Jan Dörrenhaus
  • 6,581
  • 2
  • 34
  • 45
1

You can't update existing String instance as String is immutable. What you will be able to do is create a new instance and assign it to the same variable.

zEro
  • 1,255
  • 14
  • 24
Ruchira Gayan Ranaweera
  • 34,993
  • 17
  • 75
  • 115
1

String.hashCode() method is fired only when you call it, just like any other method you write or use in Java.

So, to answer your question, the hashcode is not calculated when the String is created.

If you see the hashcode method, it's written to calculate only once and saves the precalculated hashcode value to a local variable hash

public int hashCode() {
 int h = hash;
 if (h == 0) {
  int off = offset;
  char val[] = value;
  int len = count;
  for (int i = 0; i < len; i++) {
   h = 31*h + val[off++];
  }
  hash = h;
}
return h;
} 

So, the hashcode is calculated only when the method is called

0

For most strings, the hash value will be computed the first time hashCode() is called or--in multi-threaded scenarios--every time it's called until one of the calls manages to compute and cache its value. String instances containing sequences of characters whose hash code evaluates to zero, however, will have their hash values computed every time hashCode() is called upon them. Note that it would have been possible to avoid such redundant computation by using a hash function which would never return zero for non-trivial strings (e.g. by adding the line if (!h) h=value.length+1;), but changing Java to do that now could potentially--at least in theory--break some existing code that assumes that any sequence of characters for which the built-in string hashCode() has ever yielded zero will continue to do so until the end of time.

Because writing to a variable of type String simply overwrites the contained reference without affecting the instance of String to which it had previously referred, nothing related to that previous string's hash-code (including whether or not its value has yet been computed) will be affected by the assignment.

supercat
  • 77,689
  • 9
  • 166
  • 211
0

I see this question is still "not answered". Found it by googling. So to summarize all answers and add some more value:

  • hashCode for Strings are cached on the first call to this function, there is an internal field hashCode which is zero initialized
  • Strings are immutable, but you can change them using Reflection API. Still the cached hashCode will not be updated automatically
  • Strings that initialized by character constants are always interned, so if you will write

    public static void main(String[] args) {
        String hello1 = "Hello";
        String hello2 = "Hello";
        System.out.println( hello1 == hello2 );
    }
    

you can be sure it will print out "true". if you will call for hashCode of hello1 and hello2 the hashCode will be calculated only once, since it is actually same object.

hope this information will be usefull for those who arrive there by googling.

Павел
  • 677
  • 6
  • 21