2014-01-16 1 views
0

Это кусок кода, который я использовал в книге SCJP. Я понимаю, что == сравнивает расположение памяти объектов, чтобы найти равенство, и .equals сравнивает хэш-код для определения равенства.Java confused about == в методе переопределенных равных

Мой вопрос в приведенном ниже фрагменте кода, в перекрытая равно метод сравним:

(((Moof)o).getMoofValue()) == this.getMoofValue()

в приведенном выше коде, имеет ли == сравнить расположение памяти строковое значение? Если это так, то оно должно быть ложным. Но он возвращает true. Как работает == здесь?

public class EqualsTest { 

    public static void main(String args[]){ 
     Moof one = new Moof("a"); 
     Moof two = new Moof("a"); 
     if(one.equals(two)){ 
      System.out.println("Equal"); 
     } 
     else{ 
      System.out.println("Not Equal"); 
     } 
    } 
} 



    public class Moof { 
     private String moofValue; 
     public Moof(String i){ 
      this.moofValue = i; 
     } 
     public String getMoofValue(){ 
      return this.moofValue; 
     } 
     public boolean equals(Object o){ 
      if((o instanceof Moof) && (((Moof)o).getMoofValue()) == this.getMoofValue()){ 
       return true; 
      } 
      return false; 
     } 
    } 
+0

для примитивов «==» сравнивает «свое значение» для не-примитивов «==» сравнивает ссылки ... здесь вы сравниваете 2 строки с «==», поэтому в основном вы сравниваете ссылки .. и BTW equals() сравнивает ссылки по умолчанию ... Он не сравнивает hashCode. – TheLostMind

+3

'equals()' не "сравнивает хэш-код" ... он сравнивает все, что метод написан для сравнения. –

+0

«.equals сравнивает хэш-код для определения равенства» - я был бы очень удивлен, увидев класс, который это делает. Даже в редких случаях, когда это действительно сработало, это было бы неэффективно. – user2357112

ответ

1
(Moof)o).getMoofValue()) == this.getMoofValue()) 

здесь .. Вы по-прежнему сравниваете ссылки на один и тот же объект String в пуле строк. Потому что строковые литералы интернированы автоматически.

Edit:

public class TestClass { 

    String s; 

    TestClass(String s) { 
     this.s = s; 
    } 

    public static void main(String[] args) { 

     String s1 = new String("a"); 
     String s2 = new String("a"); 
     System.out.println(s1 == s2); 

     TestClass t1 = new TestClass("a"); 
     TestClass t2 = new TestClass("a"); 
     System.out.println(t1 == t2);  // here you are comparing t1 with t2, not t1.s with t2.s so you get false... 
     System.out.println(t1.s == t2.s); // t1.s and t2.s refer to the same "a", so you get true. 

    TestClass t3 = new TestClass(s1); 
    TestClass t4 = new TestClass(s2); 
    System.out.println(t3.s == t4.s);  // false because s1 and s2 are 2 different references. 
    } 

} 
O/P : 
false 
false 
true 
false 
+0

Привет, Спасибо за ответ. Таким образом, мое понимание == сравнивает значения для примитивных и строковых литералов, но для объектов он сравнивает опорные значения. Поправьте меня, если я ошибаюсь. – Arun

+0

@Arun == check - это строки одного и того же экземпляра (как и для других объектов). Однако в спецификациях указано, что строковые литералы должны ссылаться на один и тот же объект. Итак, «a» == «a» оценивает значение true, а «a» == new String («a») принимает значение false. –

+1

'==' делает ** ровно одну вещь **; он сравнивает два значения. В случае примитивов он сравнивает примитивные значения. В случае ссылок на объекты он сравнивает опорные значения. Строки * не * специальные. –

1

Строчные литералы "a" интернированы. Каждый "a" является той же строкой в ​​памяти, поэтому они сравниваются с ==. Обратите внимание, что вы не можете полагаться на это для строк в целом. Если вы сделали следующее:

Moof two = new Moof("aa".substring(1)); 

струны будут рассматриваться != друг с другом.

0

Я понимаю, что == сравнивает ячейку памяти объектов найти равенство и .equals сравнивает хэш-код для определения равенства.

Нет, это не так. .equals() делает то, что написал тот, кто написал его. В случае Object.equals(), он возвращает результат ==.hashCode() не имеет к этому никакого отношения.

в приведенном выше коде, сопоставляет ли ячейка памяти значение строки?

Да, вы уже это сказали.

Если это так, то оно должно быть ложным. Но он возвращает true. Как работает == здесь?

Поскольку оба вхождения "a" объединены в одно и то же значение с тем же адресом.

1

Вы правы, что == сравнивает, если ссылки указывают на один и тот же объект. Таким образом, два разных объекта будут оценивать значение false с помощью ==, даже если equals() будет оценивать значение true.

S следующий код

(((Moof)o).getMoofValue()) == this.getMoofValue() 

проверки, если объекты одинаковы. Однако в Java две равные строковые константы, известные во время компиляции, должны ссылаться на один и тот же строковый объект.Глядя на

Moof one = new Moof("a"); 
Moof two = new Moof("a"); 

Мы могли бы рассматривать это как

String theValue = "a"; 
Moof one = new Moof(theValue); 
Moof two = new Moof(theValue); 

Однако, делая новую строку должен вернуть новый объект, так что вы можете попробовать

Moof one = new Moof(new String("a")); 
Moof two = new Moof(new String)"a"); 

, который приведет к равенству оценить к ложному. Более конкретный пример ниже:

String a1 = "a"; 
String a2 = "a"; 
String a3 = new String("a"); 
System.out.println(a1 == a2); // true 
System.out.println(a1 == a3); // false 

Равно как правило, не использует хэш-код для проверки равенства, но он может быть использован, чтобы сделать быструю проверку, если требуется больше сравнений. Хэш-код является числовым индикатором объекта, который, если вы внедрили класс PersonId, может быть числовым значением префикса страны и возраста человека. Таким образом, 27-летний человек из Швеции получит хеш-код 4627. Теперь, проверяя, что два PersonId ссылаются на одного и того же человека, вам может потребоваться много сравнений, но если hashCode не то же самое, тогда больше не нужно сравнивать (поскольку либо страна, либо возраст различны, а PersonIds должны относиться к разным лицам).

хэш-код используется в структурах, таких, как HashMap в качестве значения для зная, какие «ведра» для хранения объекта в.

+0

Спасибо Роджеру за ваш ответ. Я понимаю это сейчас. Цените, что вы помогаете. – Arun