2015-03-25 5 views
2
class A{ 
    int a; 
    A(){ 
     this.a = 100; 
    } 
} 
//in main, we have: 
A a = new A(), b = new A(); 
//and 
String str0 = "123", str1 = "123"; 

Почему хэш-коды str0 и str1 одинаковы, но не a и b?Почему 2 объекта имеют разные хэш-коды, но 2 строки имеют одинаковые хэш-коды в Java?

+0

str0 и str1 указывают на то же ссылки в StringPool, в то время как «а» и «б» указывают на различные ссылки в поскольку используется ключевое слово 'new'. –

+2

Это не имеет никакого отношения к String interning. – Crazyjavahacking

+0

@Crazyjavahacking Он делает. Даже если 'String' * не * переопределяет' hashCode', OP получит тот же результат, потому что 'str1' и' str2' являются ссылками на один и тот же объект, тогда как 'a' и' b' не являются. –

ответ

6

Потому что StringпереопределяетObject.hashCode() пока ваш класс не делает.

Это означает, что класс String имеет конкретную реализацию hashCode(), которая рассчитает хэш на основе значения String. Таким образом, для двух строк с одинаковым значением хэш-код будет таким же.

Если вы создаете новый класс A, например, если вы не предоставили свою собственную реализацию для hashCode(), она будет использовать реализацию по умолчанию из класса Object. Реализация по умолчанию может гарантировать только то, что хэш-коды будут одинаковыми, если они будут получены от точно таким же экземпляром.

Методы Objects.hash() (для нескольких значений) и Objects.hashCode() (для одного значения) упрощают реализацию hashCode() в ваших собственных классах. Например:

class A{ 
    int a; 

    A() { 
     this.a = 100; 
    } 

    @Override 
    public int hashCode() { 
     return Objects.hashCode(a); 
    } 
} 

Обратите внимание, что если значения атрибутов, используемых для создания изменения хэш в какой-то момент, результат hashCode(), вероятно, тоже изменится.

2

Потому что реализация hashCode() в классе java.lang.String переопределена.

Для того, чтобы использовать String в коллекциях, выполнение должно быть отменено.

1

Поскольку реализация hashCode для String была построена так, чтобы всегда возвращать один и тот же хэш-код для той же коллекции символов в заданном порядке. В то время как Object.hashCode() рассматривает объект как уникальный. Если вы хотите знать, если две строки другой объект, то вы могли бы Objects.hashCode (SomeString)

/** 
* Returns a hash code for this string. The hash code for a 
* {@code String} object is computed as 
* <blockquote><pre> 
* s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1] 
* </pre></blockquote> 
* using {@code int} arithmetic, where {@code s[i]} is the 
* <i>i</i>th character of the string, {@code n} is the length of 
* the string, and {@code ^} indicates exponentiation. 
* (The hash value of the empty string is zero.) 
* 
* @return a hash code value for this object. 
*/ 
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; 
}