厌倦了尝试使用此代码解决问题:
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
答案 0 :(得分:6)
当您在其中放置项目时,列表对象的哈希码会更改。您可以在ArrayList.hashCode文档中查看哈希码的计算方式。
通常,使用可变对象作为地图的关键不会很好。根据{{3}}:
注意:如果将可变对象用作映射键,则必须非常小心。如果在对象是地图中的键时,以影响等于比较的方式更改对象的值,则不指定映射的行为。
因此,当您第二次将列表添加到地图时,地图不会将其视为与第一个列表“相等”(因为它不是根据.equals),因此它再次添加它
答案 1 :(得分:3)
如果您想要按照身份而不是按值查找按键的地图,可以使用IdentityHashMap
类。