2013-04-18 2 views
9

Я вникаю в основы Java. Я выхожу из этого article, что метод java equals означает, что если два объекта равны, то они должны иметь один и тот же hashCode().Как работает метод equals()

Вот мой пример.

public class Equals { 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     String a = new String("a"); 
     String b = new String("a"); 
     System.out.println("a.hashCode() "+a.hashCode()); 
     System.out.println("b.hashCode() "+b.hashCode()); 
     System.out.println(a == b); 
     System.out.println(a.equals(b)); 

    } 

} 

выход:
a.hashCode() 97
b.hashCode() 97
ложные
истинно

Фактический язык Java составляет метод

public boolean equals(Object obj) { 
    return (this == obj); 
    } 

В мой вышеприведенный пример, a.equals (b) вернул true, meani g выполняется условие a == b. Но тогда почему a == b возвращает false в этом примере?

Не hashCode и адрес один и тот же? Кроме того, hashCode сравнивается, когда мы говорим a == b или что-то еще?

+0

Не отвлекайтесь на хэш-код. Это не определение равенства. Спросите себя, сколько хэш-кодов может быть, если resut является целым числом? Теперь сколько строк может быть? –

+0

Hashcode! = Адрес. Значение Hashcode обычно используется как индекс в хеш-таблице, но также часто переопределяется для получения лучшего хеша. – ArgumentNullException

ответ

13

String класс переопределил метод equals(). Пожалуйста, следуйте документации String#equals().

a.equals (б) вернулся истинный, то есть условие а == Ь выполнено

Это реализация по умолчанию equals() в Object классе, String классе переопределить реализацию по умолчанию. Он возвращает true тогда и только тогда, когда аргумент не является нулевым и является объектом String, который представляет ту же последовательность символов, что и этот объект.

Не hashCode и адрес один и тот же?

Не обязательно, для дальнейшего чтения на hashCode().

+0

Документация на Java гласит: «Насколько это разумно практично, метод hashCode, определенный классом Object, возвращает разные целые числа для отдельных объектов (это обычно реализуется путем преобразования внутреннего адреса объекта в целое число, но этот метод реализации не требуемый языком программирования JavaTM.) "[link] (http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode%28%29) – mounaim

2

Нет, хэш-код и адрес не совпадают.

Поскольку a == b не сравнивает хэш-коды.

Да, что-то еще сравнивается, когда мы говорим a == b.

(это тоже не адреса, но это достаточно близко).

Кроме того, только потому, что «равные объекты имеют равные хэш-коды» не означает, что «равные хэш-коды означают равные объекты».

1

a.equals (b) отличается от a == b.

a.equals (b) проверяет, равны ли два объекта на основе реализации equals().

a == b проверяет, имеют ли два объекта одинаковые ссылки.

Если a == b истинно, то a.equals (b) должно быть истинным, потому что они ссылаются на один и тот же объект, но не наоборот.

1

Класс String переопределяет стандартную реализацию метода equals() класса Object. Код метода equals, который вы предоставили, относится не к классу String, а к классу Object, который переопределен, является реализацией класса String, который проверяет, являются ли содержимое двух объектов одинаковыми или нет.

2

Оператор == в Java сравнивает ссылки на объекты, чтобы увидеть, относятся ли они к одному и тому же объекту. Поскольку ваши переменные a и b относятся к разным объектам, они не равны в соответствии с ==.

И метод hashCode не возвращает адрес в String, потому что этот класс имеет overridden hashCode.

Кроме того, метод equals был реализован в String для сравнения содержимого строк; поэтому a.equals(b) возвращает true здесь.

0

A и B представляют собой два отдельных объекта, которые генерируют один и тот же хеш-код из-за реализации StringhashCode(). == просто проверяет, имеет ли левая и правая стороны одинаковые ссылки. Он не вызывает метод Objectequals().

Таким образом, нет, хеши и ссылки на объекты не То же самое.

1

Hashcode для объекта предназначен для переопределения.

Для класса струнного формула используется следующим образом:

с [0] * 31^(N-1) + S [1] * 31^(N-2) + ... + S [ n-1]

Я призываю вас искать, почему 31 использовался как множитель, а не какое-то другое число.

Общее правило большого пальца для переопределения хеш-кода состоит в том, что для хэша-кода разных объектов должно быть по-разному.

Для этого рекомендуется учитывать каждое значительное поле объекта при вычислении значения хэша.

Примечание: Просто несвязанной пищу для размышлений (источник: Effective Java): Рассмотрим следующую реализацию хэш-код

int hashcode(){ 
    return 10; 
} 

Это правильное выполнение, но он также является наихудшим возможным. Читайте о том, почему.

+0

Как насчет' int hashcode() { return 75 } '? – NINCOMPOOP

+1

Это одинаково плохо, если не хуже. Возвращаемое же значение каждый раз поражает цель хеш-кода. – prashant

Смежные вопросы