2017-09-11 18 views
1
class Dog{ 
    int height; 
    int weight; 
    String name; 
} 

public class DogTest { 

    public static void main(String[] args) { 
     Dog one = new Dog(); 
     one.height=4; 
     one.name="fudo"; 
     one.weight =2; 
     Dog two = new Dog(); 
     two.height=4; 
     two.name="fudo"; 
     two.weight =2; 
     if (one.equals(two)){ 
      System.out.println("True"); 
     } 
     else{ 
      System.out.println("False"); 
     } 
    } 
} 

「False」と表示されるのはなぜですか? 「すべてのオブジェクトが同じ値であっても同じオブジェクトではない」というJavaのデフォルトの場合、これらの2つのオブジェクトが実際に等しいJavaをどのように「説得する」ことができますか?たとえ2匹の犬が同じ名前、身長、体重を持っていても、1人はダルマティナーともう1匹はピットブルで、同じ人種であっても、いつも互いに違うことがあります。なぜこの.equals()コード例が "false"を返すのですか?

PS:if(one == two){}は、両方がヒープ上の同じオブジェクトを参照しているかどうかを比較していますが、同じ順序で同じ文字がある場合はstringのequalsと比較します。

+0

あなたがオーバーライドしないとうまくいかないと、私はうまくいかないでしょう... –

+0

@Haraldそれは同じではありません。それはなぜいくつかの文字列 '=='が機能し、他の文字列は機能しない理由です。 – corsiKa

答えて

7

デフォルトではequalsメソッドには「これはメモリ内の同じオブジェクトですか?」というメッセージが表示されます。あなたがそれを上書きしない限り。

あなたはそれを上書きしませんでした。

動作は変更されませんでした。

あなたはこの

public boolean equals(Object o) { 
    if(o instanceof Dog) { 
     Dog d = (Dog)(o); 
     Dog t = this; 
     return t.height == d.height && t.weight == d.weight && t.name.equals(d.name); 
    } 
    return false; 
} 

のように新しいメソッドを追加したいと思うステファンは良い点が表示されます - 、今まで、これまでimplmentはhashCodeをせずに等しくなることはありません。常に両方のフィールドを同じにしてください。

public int hashCode() { 
    int hash = name.hashCode(); 
    hash = hash * 31 + weight; 
    hash = hash * 31 + height; 
    return hash; 
} 
+0

hashCode()メソッドもオーバーライドすることを忘れないでください。 – Stephan

+0

@Stephan 1000%はい。ハッシュマップはそうでなければ完全にバストになります! – corsiKa

3

あなたのDogクラスでequalsメソッドをオーバーライドする必要があります。そうでない場合は、それらのオブジェクトがメモリ内の同じインスタンスであるかどうかを比較しているだけです。ここで

はこれを行う方法の実装です:

class Dog{ 
    int height; 
    int weight; 
    String name; 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (!(o instanceof Dog)) return false; 

     Dog dog = (Dog) o; 

     if (height != dog.height) return false; 
     if (weight != dog.weight) return false; 
     return name != null ? name.equals(dog.name) : dog.name == null; 

    } 
} 
3

任意のIDEには、ハッシュコードを生成することを可能にするとゲッターとセッターとして自動的な方法に等しいです。

ハッシュコードがなく、等しくない場合は、オブジェクトが同じメモリ位置にあることができないため、falseになります。

あなたの(作業)例以下:

class Dog{ 
    int height; 
    int weight; 
    String name; 

    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + height; 
     result = prime * result + ((name == null) ? 0 : name.hashCode()); 
     result = prime * result + weight; 
     return result; 
    } 
    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     Dog other = (Dog) obj; 
     if (height != other.height) 
      return false; 
     if (name == null) { 
      if (other.name != null) 
       return false; 
     } else if (!name.equals(other.name)) 
      return false; 
     if (weight != other.weight) 
      return false; 
     return true; 
    } 

    public static void main(String[] args) { 
     Dog one = new Dog(); 
     one.height=4; 
     one.name="fudo"; 
     one.weight =2; 
     Dog two = new Dog(); 
     two.height=4; 
     two.name="fudo"; 
     two.weight =2; 
     if (one.equals(two)){ 
      System.out.println("True"); 
     } 
     else{ 
      System.out.println("False"); 
     } 
    } 
} 

結果:

enter image description here

ハッシュコードを生成し、日食で自動的な方法に等しい:あなたのクラスで

右クリックし、 :

enter image description here

+0

あなたが言うことを漠然と理解していますが、私は(まだ)このコードの実装を理解していません。どんな場合でも、ありがとう! – Krushe

+0

私はコードの任意の行を書いていない、私はあなたに 'one.equals(2)'を呼び出すと、それは私のためにそれを行う日食を許可する、あなたはオーバーライドequalsを呼び出す、** this **そのオブジェクト** one * *および** obj **オブジェクト** 2 **。 – Frank

+0

説明をいただきありがとうございます、今はちょっとはっきりしているようです。どうすれば日食をあなたのためにやるのですか? – Krushe

関連する問題