2012-09-14 19 views
5

こんにちは私はHashMapを使用して、BulletinBoardでサービスとサービスリクエストを追跡しています。しかし、私は重複したキーを取得しているので、私はハッシュコードを持っている必要があります。誰がこれがなぜそうかもしれないと言うことができますか?なぜ私のHashMapは重複キーを許可していますか?

のkeySetの内容:

Services: [1, 1, 6, 6, 3] 
Requests: [8, 7, 6, 5, 8, 4, 5, 6, 2] 

がここに関連するコードです:

private static final HashMap<Advert, Integer> services = new HashMap<>(); 
... 

public class Advert { 

private int id; 
private BoardPoster poster; 

public Advert(BoardPoster poster) { 
    this.poster = poster; 
} 

public BoardPoster getPoster() { 
    return poster; 
} 

public void spawn() { 
    id = RANDOM.nextInt(ADVERT_RANGE); 
} 

public int getID() { 
    return id; 
} 

@Override 
public String toString() { 
    return Integer.toString(id); 
} 

@Override 
public boolean equals(Object o) { 
    if (o != null && o instanceof Advert) { 
     return ((Advert) o).id == id; 
    } 
    return false; 
} 

@Override 
public int hashCode() { 
    return 67 * 5 + this.id; 
} 
} 
+4

1つの発言:「o!= null && instanceof Advert」をチェックすることは冗長です。 'o instanceof Advert'は' o'が 'null'ならば' false'を返します。 Javaでは、 'null'は何かの型とはみなされないので、すべてのインスタンスのチェックは失敗します。 – Brian

+1

'id'は' int'なので、あなたはハッシュコードを単純化することができます: 'return this.id;'。 – assylias

+0

@assyliasハッシュコードを実行するのは悪い方法です。なぜなら、実際にはハッシングではないからです。 'this.id%1000'を返す方が良い選択肢かもしれません。 –

答えて

18

有力な理由は、あなたがキーとして使用するオブジェクトが変更可能であるということです。したがって、次のような場合:

map.put(anAdvert, 1); 
anAdvert.spawn(); //modifies id, which affects hashcode and equals 

マップの動作は予期しないものになります。

CF Map's javadoc

注:可変オブジェクトがマップのキーとして使用されている場合には、十分な注意を払わなければなりません。オブジェクトがマップ内のキーである間に等価比較に影響するようにオブジェクトの値が変更された場合、マップの動作は指定されません。

+6

+1のキーが変更可能です。 – kosa

+0

このようなプロパティには 'final'キーワードを使用することをお勧めします。 –

+1

マップキーとして可変オブジェクトを使用しないでください! –

関連する問題