HashMap / ArrayList中的错误或错误的代码?

时间:2016-06-08 17:56:13

标签: java dictionary hash

厌倦了尝试使用此代码解决问题:

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

2 个答案:

答案 0 :(得分:6)

当您在其中放置项目时,列表对象的哈希码会更改。您可以在ArrayList.hashCode文档中查看哈希码的计算方式。

通常,使用可变对象作为地图的关键不会很好。根据{{​​3}}:

  

注意:如果将可变对象用作映射键,则必须非常小心。如果在对象是地图中的键时,以影响等于比较的方式更改对象的值,则不指定映射的行为。

因此,当您第二次将列表添加到地图时,地图不会将其视为与第一个列表“相等”(因为它不是根据.equals),因此它再次添加它

答案 1 :(得分:3)

如果您想要按照身份而不是按值查找按键的地图,可以使用IdentityHashMap类。