0

我创建了一个HashMap有十个字段的:key类型是Stringvalue类型是一个double[]

当我尝试使用 更新地图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[]哈希表条目。所以很自然,当您更新与一个名称关联的值时,您实际上是在更新与所有名称关联的值。


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 回答
1

您在循环的每次迭代中都使用相同的数组。改变

double[] newVal = {0.0, 0.0};

double[] newVal = new double[]{0.0, 0.0};
于 2013-08-21T09:32:06.637 回答
1

您只需创建一个 double[],因此所有键/值对共享相同的值。

尝试创建一个新数组:

table.put(name, new double[]{newVal[0], newVal[1]);

只是一个快速破解,肯定有更优雅的解决方案。

于 2013-08-21T09:32:47.623 回答