2009-04-22 23 views
3

はここでテストケースここ たJavaのジェネリックペア<文字列、文字列>適切

import java.lang.*; 
import java.util.*; 

public class Pair<TYPEA, TYPEB> implements Comparable< Pair<TYPEA, TYPEB> > { 
    protected final TYPEA Key_; 
    protected final TYPEB Value_; 

    public Pair(TYPEA key, TYPEB value) { 
    Key_ = key; 
    Value_ = value; 
    } 
    public TYPEA getKey() { 
    return Key_; 
    } 
    public TYPEB getValue() { 
    return Value_; 
    } 
    public String toString() { 
    System.out.println("in toString()"); 
    StringBuffer buff = new StringBuffer(); 
     buff.append("Key: "); 
     buff.append(Key_); 
     buff.append("\tValue: "); 
     buff.append(Value_); 
    return(buff.toString()); 
    } 
    public int compareTo(Pair<TYPEA, TYPEB> p1) { 
    System.out.println("in compareTo()"); 
    if (null != p1) { 
     if (p1.equals(this)) { 
     return 0; 
     } else if (p1.hashCode() > this.hashCode()) { 
      return 1; 
     } else if (p1.hashCode() < this.hashCode()) { 
     return -1; 
     } 
    } 
    return(-1); 
    } 
    public boolean equals(Pair<TYPEA, TYPEB> p1) { 
    System.out.println("in equals()"); 
    if (null != p1) { 
     if (p1.Key_.equals(this.Key_) && p1.Value_.equals(this.Value_)) { 
     return(true); 
     } 
    } 
    return(false); 
    } 
    public int hashCode() { 
    int hashCode = Key_.hashCode() + (31 * Value_.hashCode()); 
    System.out.println("in hashCode() [" + Integer.toString(hashCode) + "]"); 
    return(hashCode); 
    } 
} 

Pair.java

だのです.containsKeyコールは、(私はめちゃくちゃ期待して)ペア< "Three"、 "Three">が真であるところに格納された値を返すべきです - 私は "SEVEN"の値を持つStringを取得する必要があります。

Running in equals() 
in hashCode() [1976956095] 
in hashCode() [1976956126] 
in hashCode() [1976956096] 
in hashCode() [1976956127] 
in hashCode() [1976956097] 
in hashCode() [1976956128] 
in hashCode() [1976956159] 
in equals() 
in equals() 
in hashCode() [1976956159] 
in hashCode() [1976956159] 
in compareTo() 
in equals() 
in compareTo() 
in equals() 
starting containsKey search 
in hashCode() [1976956159] 
starting containsKey search2 
in hashCode() [1976956159]  <--- Bug here? 

Never reaches 
      String result = hm1.get(pSrch); 

が両p7.hashCode()とpSrch.hashCode()等しく、p7.equals(pSrch)とpSrch.equals(P7)、およびhm1.containsValue(P7)である:ここで出力されます== true、私はhm1.containsValue(pSrch)もtrueを返すと思いますが、そうではありません。私は何が欠けていますか?

答えて

24

java.lang.Objectクラスの equalsメソッドをオーバーライドする必要があります。

代わりににはがオーバーロードされています。追加のバージョンにはPairが必要です。絶対に呼び出されない全く異なる方法。

@Override 
public boolean equals(Object o) { 
    System.out.println("in equals()"); 
    if (o instanceof Pair) { 
    Pair<?, ?> p1 = (Pair<?, ?>) o; 
    if (p1.Key_.equals(this.Key_) && p1.Value_.equals(this.Value_)) { 
     return(true); 
    } 
    } 
    return(false); 
} 

あなたがオーバーライドとして機能する予定の方法に@Overrideアノテーションを使用し、この種の誤りを避けるために:あなたのequalsは次のようなものと交換してください。コンパイル時にエラーが発生すると、コンパイル時エラーが発生します。

+0

Key_とValue_はnullでもかまいません。 (間違った名前、元の質問者btw) –

+0

私は元のポスターです、私は間違った名前のビットに従うかどうかわかりません? equals()のp1.Key_はnullでもかまいませんか?はい正解。ありがとうございました。 –

+1

本当にPairのサブクラスをPairのインスタンスと等しくしたいのでない限り、単にinstanceofではなくthis.getClass()== o.getClass()をテストしたいと思うかもしれません。これにより、あなたのequals()実装が反射的ではなくなります。つまり、a.equals(b)!= b.equals(a)が可能です。これはObject.equals()の規定に違反します。 –

5

"contains containsKey search2"の後に "equals()"が表示されないことに気づかなければなりません。また、HashMapにデバッグして、.equals()メソッドが呼び出され、falseを返すことも確認できます。

public boolean equals(Pair<TYPEA, TYPEB> p1) 

public boolean equals(Object obj) 

public boolean equals(Object obj) { 
    if (!(obj instanceof Pair)) return false; 
    Pair p1 = (Pair) obj; 

にコードを変更し

java.lang.Objectの

で定義されていて、それが動作オーバーライドしないためです。将来オーバーライドすると思われるメソッドの前に@Overrideアノテーションを置くことで、このようなバグを避けることができます。実際にそれをオーバーライドしていない場合、コンパイラはあなたに指示します。この

@Override public boolean equals(Pair<TYPEA, TYPEB> p1) 

コンパイルエラーが発生します。この

@Override public boolean equals(Object obj) 

はありません。また、良いIDE(Intellij IDEAなど)は、どのメソッドがオーバーライドされているかを示します。

+0

私はそれが何かシンプルであることを知っていましたが、hashCode()への呼び出しはHashMap自体から来ていました - 私はそれがhashCodeによる高速マッピングであると考えていました。 –

関連する問題