1

オブジェクトのインスタンス変数を変更したときに、Map のキーとしてオブジェクトを取得しようとしています。私が知る限り、Map 構造体でキー オブジェクトを検索すると、hashCode メソッドが最初と同じ値を返したときに表示されるはずです。ただし、次のコードに基づいて、変数 weight の値を変更したメソッド get() を介してオブジェクトを取得できません。

public class Car  implements Comparable<Car> {

 int weight;
 String name;

 public Car(int w, String n) {
    weight=w;
    name=n;
 }

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

}

public int hashCode(){
    return weight/2 + 17;
}

public String toString(){
    return "I am " +name+ " with weight: "+weight;
}


public int compareTo(Car d){
    if(this.weight>d.weight)
        return 1;
    else if(this.weight<d.weight)
        return -1;
    else
        return this.name.compareTo(d.name);
}

}


public static void main(String[] args) {
    Car d1 = new Car(107, "a");
    Car d2 = new Car(110, "b");
    Car d3 = new Car(110, "c");
    Car d4 = new Car(107, "a");

    Map<Car, Integer> m = new HashMap<Car, Integer>();
    m.put(d1, 1);
    m.put(d2, 2);
    m.put(d3, 3);
    m.put(d4, 16);

    System.out.println(m.get(d1).toString());
    d1.weight = 34;
    System.out.println(m.get(new Car(34, "a")));

    for(Map.Entry<Car, Integer> me : m.entrySet())
        System.out.println(me.getKey().toString() + " value: " +me.getValue());

}

出力は次のとおりです。

16

null

I am a with weight: 34 16

I am c with weight: 110 3

I am b with weight: 110 2

ただし、 weight の値を変更しない場合 (行を省略します: d1.weight = 34;)、コード行のみを使用します。

System.out.println(m.get(new Car(107, "a")));

出力は次のとおりです。

16

16

I am a with weight: 107 value: 16

I am c with weight: 110 value: 3

I am b with weight: 110 value: 2

実際にオブジェクトを見つけます。両方の方法で期待される出力になりますか、それとも最初のバージョンでもオブジェクトを見つけて取得する必要がありますか?

4

2 に答える 2

6

変更可能なオブジェクトをキーとしてハッシュテーブルに格納する場合は、十分に注意する必要があります。ハッシュ コードは、オブジェクトの挿入時に一度だけ計算されます。後でハッシュ コードに影響を与えるような方法でオブジェクトを変更すると、オブジェクトを見つけることができなくなる可能性が非常に高くなります。

このような変更が行われるたびに、オブジェクトを削除して再挿入する必要があります。

于 2012-12-01T17:24:31.807 に答える
0
System.out.println(m.get(new Car(34, "a")));

ハッシュコード 34 のキー オブジェクトが含まれていないため、マップはここで null を返します。

ただし、

System.out.println(m.get(new Car(107, "a")));

ハッシュコード 70 のキー オブジェクトが含まれているため、マップはオブジェクトを返します。

于 2012-12-01T17:31:42.983 に答える