0

Should a merge of hashes of two String objects be the same as a hash of their concatenation? I was using XOR ^ operator (as advised here) and got a different result.

What I am doing wrong?

String a = "A";
String b = "B";
String ab = a+b;
int i = a.hashCode() ^ b.hashCode();

System.out.println(
    a.hashCode()+"\n"+
    b.hashCode()+"\n"+
    ab.hashCode()+"\n"
    i);
Mureinik
  • 297,002
  • 52
  • 306
  • 350
max3d
  • 1,437
  • 15
  • 16
  • 3
    No. Why would you expect them to be the same? Did you check the documentation for `String.hashCode()`? – shmosel Mar 11 '18 at 18:52
  • *"What I am doing wrong?"* Your thinking, is what you're doing wrong. Why would you think XOR'ing hashes would be the same. `String` can create the hash in any way it wants. It could send the text through a cryptographic function if it wanted to *(it won't, too slow)*. But as far as you're concerned, it might as well have. You should never expect any particular hash value for a particular text. New versions of Java may even change the algorithm used. – Andreas Mar 11 '18 at 19:08
  • 3
    @Andreas Not really. The algorithm is in the documentation. It can't be changed now. – shmosel Mar 11 '18 at 22:25
  • @shmosel Technically, nothing stops a new Java SE version JSR or JEP from changing the algorithm. – Mark Rotteveel Mar 12 '18 at 15:21
  • @MarkRotteveel Technically, nothing stops the next JLS from swapping the meaning of `true` and `false`. – shmosel Mar 12 '18 at 15:31

1 Answers1

1

The premise of the question is wrong. The only hard requirement for hashCode() is that two objects that are equal (i.e., calling a.equals(b) returns true) has equal hash codes (i.e., a.hashCode() == b.hashCode() returns true.

In fact, by reading through String#hashCode()'s javadoc, it's state that:

The hash code for a String object is computed as
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]

using int arithmetic, where s[i] is the ith character of the string, n is the length of the string, and ^ indicates exponentiation. (The hash value of the empty string is zero.)

So clearly, concatinting two strings will not result in a string that has a hash code equal to the xor of hash codes of the strings that made it up.

Mureinik
  • 297,002
  • 52
  • 306
  • 350