我创建了一个包含十个字段的HashMap
:key
类型为String
,value
类型为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);
}
答案 0 :(得分: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;
}
答案 1 :(得分:1)
您在循环的每次迭代中使用相同的数组。 变化
double[] newVal = {0.0, 0.0};
到
double[] newVal = new double[]{0.0, 0.0};
答案 2 :(得分:1)
您只创建一个double [],因此所有键/值对共享相同的值。
尝试创建新阵列:
table.put(name, new double[]{newVal[0], newVal[1]);
快速破解,肯定有更优雅的解决方案。