ArrayList <String>对象指向null。为什么?

时间:2019-08-14 23:57:18

标签: java arraylist

我有一段代码,它接受一个ArrayList<String>对象,并最终将该对象添加到HashMap对象中作为键。当我打印哈希图时,键的值都是正确的,而它们都是空的。

我已经知道我可以通过传递ArrayList<String>对象的副本来修复代码,并且可以解决我的问题(即buildHash(new ArrayList<String>(key))。但是为什么它指向空值呢?

HashMap<ArrayList<String>, ArrayList<String>> hash = new HashMap<>();
ArrayList<String> key = new ArrayList<String>();

for (int i = 0; i <= 9999999; i++) {
     key.add(//different strings depending on the iteration);
     if ( !hash.contains(key) ) {
          buildHash(key);
     }
     key.clear();
}

private void buildHash(ArrayList<String> key) {
    ArrayList<String> follows = new ArrayList<String>();
    for (int index = 0; index <= 9999999; index++) {
         // add stuff to follows...
    }
    hash.put(key, follows);
}

我认为该键的值将被添加到哈希中,并且该哈希的键将指向被key.clear()清除之前的值。这样,我可以反复使用键,而无需在内存中创建另一个对象。

我是Java(和编码)的新手,所以我可能很幼稚,但我认为我可以通过使用ArrayLists的可变性(而不是Lists)来节省内存,因为并且为此项目生成的密钥已达到数百万(甚至更多)。有没有避免的办法?如果没有,我还能做其他优化吗?

1 个答案:

答案 0 :(得分:1)

根据记录,ArrayList::clear从列表中删除所有元素。因此,您正在清除内容。

  

利用ArrayLists的可变性

您确实想不要输入密钥。在映射中用作键的对象绝不可修改,而不能影响哈希值计算的结果或影响equals方法的结果。您希望在他们更改名字后在电话簿中找到某人吗?

我很难想象您想在列表中的哪个位置使用列表作为键。

至于试图“保存内存”……不要。新程序员应该担心的最后一件事是节省RAM。编写简单的代码,易于阅读,易于编辑。然后让JVM为您完成优化工作。

我建议您不要这么聪明。花一些时间看其他代码。搜索堆栈溢出和其他地方以查找类似于您的逻辑问题或所使用的类的代码。然后研究代码示例。