列出清除与新列表

时间:2014-10-15 20:30:15

标签: java arraylist hashmap

为什么.clear()即使在放入散列图之后也会破坏我的对象列表,而不是只创建该对象的新实例?

变量声明:

List<Pricing_Data> toAdd = new ArrayList<Pricing_Data>();
HashMap<String, List<Pricing_Data>> pricingMap_twelve = new HashMap<String, List<Pricing_Data>>();

按预期工作的示例:

pricingMap_twelve.put(pricing.get(y).getName(), toAdd);
toAdd = new ArrayList<Pricing_Data>();

在添加到所述hashmap之后,hashmap中的数据意外破坏示例:

pricingMap_twelve.put(pricing.get(y).getName(), toAdd);
toAdd.clear();

我猜这与我遇到的类似问题有关,当我第一次搞乱日历时,数据实际上并没有放入&#39;进入对象但是指向原始的指针?

4 个答案:

答案 0 :(得分:2)

使用toAdd.clear方法时,您将清除toAdd变量列表当前引用的内容。

使用toAdd = new ArrayList<Pricing_Data>()时,现在toAdd变量指向到新参考。由toAdd保存的引用仍将由pricingMap_twelve存储在引用保留中。

更多信息:

答案 1 :(得分:2)

这是clear的定义。它与new不同。 new创建一个新对象,并为您提供对新对象的引用。给定对象的方法clear采用相同的对象并擦除其中的内容。

重要的是要理解将对象放在列表中不会将对象的复制放在列表中。它将引用放入列表中的该对象。变量中的引用和列表中的引用指向相同的对象,因此如果清除它,列表也指向已清除的对象。

所以你必须使用new,而不是clear

答案 2 :(得分:1)

严格来说,Java中没有指针,但引用的行为方式大致相同:如果将引用对象添加到集合中,然后更改该对象,则集合中存储的项目也会发生变化。特别是,当您调用clear时,结果将通过集合的所有引用显示,包括您可能已放置在其他集合中的任何引用。

这里有一个有用的推论是,如果要将集合添加到另一个容器中,您几乎总是希望在集合中创建一个新副本,而不是容器本身。这可以避免常见的错误:

List<List<String>> sentences = new ArrayList<List<String>>();
List<String> words = new ArrayList<String>();
// This is broken!
while (haveMoreData(myFile)) {
    readNextSentence(myFile, words);
    sentences.add(words);
    words.clear();
}

上面的代码是错误的,因为它会尝试将同一个列表words多次放入sentences,并在两者之间清除它。最终会得到列表中最后一个句子的多个实例。

使用new修复了问题:

List<List<String>> sentences = new ArrayList<List<String>>();
while (haveMoreData(myFile)) {
    List<String> words = new ArrayList<String>();
    readNextSentence(myFile, words);
    sentences.add(words);
}

现在每次迭代都会为words获取自己的容器,避免因重用和清除同一个集合而导致的别名问题。

答案 3 :(得分:1)

非基本类型的Java变量将引用保存到对象。传递引用并将它们分配给其他变量,数组等仅影响引用,而不影响它引用的对象。虽然它很常见,但它也松散,有时候说变量&#34;包含&#34;一个对象。

因此,当您使用Map.put()时,您将地图引用注册到指定的键和值;存储在其他地方的引用(例如变量toAdd)仍然引用同一个对象。

当然,在将新对象的引用分配给变量之后,该变量不再与之前引用的对象相关联。