0

HashMap10 個のフィールドを持つ を作成しました。タイプkeyStringで、valueタイプは andouble[]です。

を使用してマップを更新しようとするput(String id, double[] newVal)と、「id」キーに関連付けられた値だけでなく、マップ内のすべての値が更新されます。

この問題を解決するにはどうすればよいですか?

      for (int j = 0;j<attrIndex.length;j ++){

        String name = train.attribute(attrIndex [j]).name();
        double g = eval.evaluateAttribute(attrIndex[j]);

        double[] newVal = {0.0, 0.0};
        double w = 1;
        if (g == 0.0) 
            w = 0.5;

        newVal = table.get(name);
        newVal[0] += g;
        newVal[1] += w;
        table.put(name, newVal);

    }
4

3 に答える 3

2

本当のバグは、あなたが示したコードにはないと確信しています。このことを考慮:

    double[] newVal = {0.0, 0.0};
    // ...
    newVal = table.get(name);   // LOOK HERE
    newVal[0] += g;
    newVal[1] += w;
    table.put(name, newVal);

一見すると、新規作成してdouble[]から更新しているように見えます。しかし実際には、double[]更新されているのは、ハッシュ テーブルから取得しているものです。(double[]初期化しているものは捨てられており、putコード内の操作は冗長です。)

では、これがどのように問題になるのでしょうか。まあ、それ自体はそうではありません。しかし、これは、他の何かtableがエントリの初期セットで取り込まれている必要があることを意味します。また、症状は、テーブルにデータを入力するコードが次のようになっていることを示唆しています。

   double[] val = {0.0, 0.0};
   for (String name : ...) {
       table.put(name, val);
   }

...すべて同じを共有double[]する複数のハッシュ テーブル エントリを作成しています。当然のことながら、1 つの名前に関連付けられた値を更新すると、実際にはすべての名前に関連付けられた値が更新されます。


JB Nizet の (現在は削除された) コードが問題を修正した理由はdouble[]、エントリを更新するたびにオブジェクトを置き換えていたためです。

しかし、これを修正するより良い方法は、初期化コードを次のように変更することです。

   for (String name : ...) {
       double[] val = {0.0, 0.0};
       table.put(name, val);
   }

また、更新コードを次のように単純化できます。

for (int j = 0;j<attrIndex.length;j ++){
    String name = train.attribute(attrIndex [j]).name();
    double g = eval.evaluateAttribute(attrIndex[j]);
    double w = 1;
    if (g == 0.0) 
        w = 0.5;
    double[] val = table.get(name);
    val[0] += g;
    val[1] += w;
}
于 2013-08-21T14:46:52.383 に答える