2

だから、私は自分自身を値HashMapにマッピングするためにを使用しようとしています。私のオブジェクトは以下にあります(簡潔にするためにいくつかのコードが削除されています)ObjectString

public class RouteHeadsignPair {
    String route;
    String headsign;

    public RouteHeadsignPair(String n_route, String n_headsign) {
        route = n_route.toLowerCase();
        headsign = n_headsign.toLowerCase();
    }

    public String getRoute () {
        return route;
    }

    public String getHeadsign() {
        return headsign;
    }

    public boolean equals(RouteHeadsignPair other) {
        return(other.getRoute().equals(route) && other.getHeadsign().equals(headsign));
    }

    public int hashCode() {
        return(route.hashCode());
    }
}

テキストファイルからデータをロードすることにより、これらのオブジェクトの束を文字列にマッピングしています。後で、(独立した)ユーザー入力に基づいて、オブジェクトHashMapを使用してクエリを実行しようとします。RouteHeadsignPaircontainsKey()はfalseを返し、get()はnullを返します。これは、キーをマップに追加したことがないかのようです。しかし、奇妙なことに、以下のコードを使用してマップを反復処理すると(ここnewKeyで、はRouteHeadsignPairユーザー入力から作成されます)

RouteHeadsignPair foundKey = null;
Iterator<RouteHeadsignPair> keysInMap = routeHeadsignToStopIdMap.keySet().iterator();
while(keysInMap.hasNext()) {
    RouteHeadsignPair currKey = keysInMap.next();

    if(currKey.equals(newKey)) {
        System.err.println("Did find a key with an equals() == true!");
        foundKey = currKey;
    }
}

System.err.println("Value in map? " + routeHeadsignToStopIdMap.containsKey(newKey)  + "( hashcode = " + newKey.hashCode() + 
        ", equals = " + newKey.equals(foundKey) + ")");
System.err.println("foundKey in map? " + routeHeadsignToStopIdMap.containsKey(foundKey)  + "( hashcode = " + foundKey.hashCode() + 
        ", equals = " + foundKey.equals(newKey) + ")" );

コードのフォーマットについてお詫びします。遅くなり、不機嫌になります。

次の出力が得られます

Did find a key with an equals() == true!

その後

Value in map? false( hashcode = 1695, equals = true)
foundKey in map? true( hashcode = 1695, equals = true)

したがって、キーを繰り返し処理して、戻るキーを探すequals()と、1つが見つかりますhashCode()。これは、どちらも同じです。とhashCode()が同じでtrueを返す場合、値を返してtrueを返すべきではありませんか?私はここで何が間違っているのですか?newKeyfoundKeyfoundKey.equals(newKey)HashMap.get(key)containsKey()

4

1 に答える 1

9

あなたはオーバーライドしていませんObject.equals-あなたはパラメータタイプのためにそれをオーバーロードしています。診断コードはオーバーロードを呼び出しますが、マップコードは呼び出しません(それについて知らないため)。

の署名を持つメソッドが必要です

public boolean equals(Object other)

注釈を使用する場合、@Override何かを適切にオーバーライドしないとエラーが発生します。

other最初にのインスタンスであるかどうかを確認してからRouteHeadSignPair、キャストする必要があります。クラスをファイナルにすればRouteHeadSignPair、まったく同じクラスかどうかなどを気にする必要はありません。

ちなみに、ハッシュコードは不必要に衝突することに注意してください。ハッシュコードを生成するためにroute ハッシュの両方を使用すると、headSignマップルックアップがより効率的になる可能性があります。(同じルートでヘッドサインが異なるインスタンスが複数ある場合、キーを検索するときにマップがそれらすべての同等性をチェックする必要がない場合に便利です。)

于 2012-08-24T07:33:54.080 に答える