【发布时间】:2016-10-09 03:25:21
【问题描述】:
厌倦了尝试使用此代码解决问题:
public class MapTest {
static class T{
static class K{}
}
static Map<List<T.K>, List<String>> map = new HashMap<>();
static List<String> test(List<T.K> list, String s){
List<String> l = map.get(list);
if (l == null){
l = new ArrayList<String>();
System.out.println("New value()");
map.put(list, l);
}
l.add(s);
return l;
}
public static void main(String s[]){
ArrayList<T.K> list = new ArrayList<T.K>();
test(list, "TEST");
list.add(new T.K());
List<String> l = test(list, "TEST1");
System.out.println(l.size());
}
}
它应该只为地图创建一个新的列表值,但输出如下:
New value
New value
1
我在其中插入值后,列表的哈希码发生了错误。 我希望“新值”只出现一次,大小为 2,而不是 1。 它只是JVM问题还是更普遍的问题? 我的一个是 Oracle JVM 1.8.0_65
【问题讨论】:
-
这个例子说明了为什么使用可变类型和 Map 键是一个坏主意。
list.add(new T.K());导致列表生成不同的哈希码,因为它不再为空,因此地图无法再找到现有实例。顺便说一句:List#hashCode的 JavaDoc 很好地解释了它的行为。 -
一般来说:java标准库没有bug。如果他们有错误,他们是非常微妙的。含义:可以非常自信地假设图书馆是正确的;而那些想法/假设......不是。
-
@Jägermeister,这有点强。我个人在 Java 标准库中发现了错误,这已被接受的错误报告所证实。还有很多很多其他人报告的错误。尽管如此,你是对的,一个人的一般姿态应该是观察到的任何不当行为几乎可以肯定是因为自己的代码不好,而不是因为标准库有错误。
-
@ManoDestra
toString对地图并不重要。 -
抱歉,我的意思是
hashCode()。如果他希望返回引用,他可以使用System.identityHashCode(list)。但是,他不应该使用这种 IMO 密钥。 stackoverflow.com/questions/580984/…
标签: java dictionary hash