2015-06-22 34 views
1

我知道当你创建一个ArrayList并且声明它时你把它引用到另一个ArrayList中时它只能引用另一个ArrayList,所以对第二个的更改会改变第一个。但是在面对这个问题时我感到困惑。如何创建一个不涉及另一个的Arraylist?

ArrayList <Productos> d3 = abd.dadesProductos(); 
ArrayList <Productos> dades2 = new ArrayList <Productos>(); 
System.out.println("before clear() + size= "+d3.get(i).configurables.size());//43 
dades2.add(d3.get(i)); 
dades2.get(dades2.size()-1).configurables.clear(); 
System.out.println("after clear() + size= "+d3.get(i).configurables.size());//0 

的问题是,从最后一项清除参数配置属性(另一个数组列表)之后加入到dades2还会清除它从D3,我不希望这发生在所有......这是为什么呢发生如果我创建一个ArrayList为new ArrayList <Productos>();

我会appreaciate任何帮助。

一些额外的信息。

我试图创建一个新的构造是这样的:

Productos(Productos p) 
    { 
     this(p.entity_id, p.model, p.sku, p.name, p.weight, p.visibility, p.material, p.attribute_set_name, p.image, p.category_ids, p.category_ids2, p.color, p.color2, p.color3, p.cpsp_enable, p.created_at, p.description, p.colorswatch_disabled_category, p.colorswatch_disabled_product, p.msrp_display_actual_price_type, p.options_container, p.fcpm_enable, p.is_recurring, p.image_label, p.manage_stock, p.manufacturer, p.max_sale_qty, p.meta_description, p.meta_keyword, p.meta_title, p.category_positions, p.price, p.type_id, p.fcpm_second_attribute, p.fcpm_template, p.fcpm_template_position, p.short_description, p.fcpm_showfdd, p.fcpm_show_grandtotal, p.fcpm_second_layout, p.fcpm_show_link, p.fcpm_checkbox, p.fcpm_show_image, p.fcpm_show_rowtotal, p.fcpm_show_stock, p.special_price, p.special_from_date, p.special_to_date, p.status, p.tax_class_id, p.tier_price, p.url_key, p.updated_at, p.url_path, p.dimensions, p.mindeco, p.talla, p.trang1, p.trang2, p.trang3, p.trang4, p.trang5, p.tprice1, p.tprice2, p.tprice3, p.tprice4, p.tprice5, p.maxCols, p.marcPrio, p.configurables, p.marcajes); 
    } 

而且同样认发生了什么。我认为这是因为我通过引用来分配ArrayList可配置。

我试图做一些深层克隆,但没有成功。不明白如何使用它。

SOLUTION

dades2.add(new Productos(d3.get(i))); 


Productos(Productos p) 
    { 
     this(p.entity_id, p.model, p.sku, p.name, p.weight, p.visibility, p.material, p.attribute_set_name, p.image, p.category_ids, p.category_ids2, p.color, p.color2, p.color3, p.cpsp_enable, p.created_at, p.description, p.colorswatch_disabled_category, p.colorswatch_disabled_product, p.msrp_display_actual_price_type, p.options_container, p.fcpm_enable, p.is_recurring, p.image_label, p.manage_stock, p.manufacturer, p.max_sale_qty, p.meta_description, p.meta_keyword, p.meta_title, p.category_positions, p.price, p.type_id, p.fcpm_second_attribute, p.fcpm_template, p.fcpm_template_position, p.short_description, p.fcpm_showfdd, p.fcpm_show_grandtotal, p.fcpm_second_layout, p.fcpm_show_link, p.fcpm_checkbox, p.fcpm_show_image, p.fcpm_show_rowtotal, p.fcpm_show_stock, p.special_price, p.special_from_date, p.special_to_date, p.status, p.tax_class_id, p.tier_price, p.url_key, p.updated_at, p.url_path, p.dimensions, p.mindeco, p.talla, p.trang1, p.trang2, p.trang3, p.trang4, p.trang5, p.tprice1, p.tprice2, p.tprice3, p.tprice4, p.tprice5, p.maxCols, p.marcPrio, p.marcajes); 
     ArrayList <Configurable>configs=p.configurables; 
     for(int i=0;i<configs.size();i++) 
     { 
      this.configurables.add(new Configurable(configs.get(i))); 
     } 
    } 


Configurable(Configurable c) 
    { 
     this(c.codip, c.codic, c.sku, c.color, c.color2, c.color3, c.talla, c.price, c.image, c.trang1, c.trang2, c.trang3, c.trang4, c.trang5, c.tprice1, c.tprice2, c.tprice3, c.tprice4, c.tprice5); 
    } 

,因为它似乎为Productos创建一个新的构造还不够我还创建了一个新的构造函数Configurable并在Productos的构造函数中用a逐个复制项目。现在看起来很有效。

+0

你在那里使用'i',就像'd3.get(i)' - 是for循环中的一些代码吗? –

+0

你的意思是复制一份吗? – jgr208

+0

是的,我做气垫船。当我在第一个'println'检查结果时,我定义了阵列列表和部分之间的部分。 – danibg

回答

5

发生这种情况的原因是您正在更改List中的对象而不是List本身。这里的两个列表都包含同一个对象,所以当你从一个列表中选择get()时,你会得到另一个列表中包含的同一个对象。

解决此问题的方法是将Productos类的副本插入到新数组中,而不是已经创建的对象。根据您的Productos类的复杂性,您可以创建一个复制构造函数,或者对其执行clone()以复制它。

+0

我曾尝试创建'Productos'的副本构造函数,但同样的事情发生。当分配它是这样的:'dades2.add(new Productos(d3.get(i)));' – danibg

+0

在对象内部,你复制列表还是复制列表通过分配列表或创建一个新列表并复制名单的成员?看到我关于浅/深层复制的评论。 –

+0

我编辑了这个问题。谢谢你的时间! – danibg

2

的问题是不是数组列表,但你的任务:

dades2.add(d3.get(i)); 

你的对象需要实现某种类型clone()功能,他们创造充满了相同的数据和原来的一个新的实例。 所以上面的行应该成为

dades2.add(d3.get(i).clone()); 

你可能要研究的另一个课题是那么浅拷贝和深拷贝之间的差异。

+0

假设'configurables'是一个'List',那么你将无法克隆由'd3.get(i)'返回的引用所指向的对象。 – CKing

+0

这就是为什么我提到浅/德普副本:-)据我所知,它取决于实施克隆() –

0

要创建ArrayList的独立副本,您需要迭代每个项目并单独克隆它们,随时将克隆放入新的ArrayList。下面是一个例子证明:

public static List<Productos> cloneList(List<Productos> list) { 
    List<Productos> clone = new ArrayList<Productos>(list.size()); 
    for(Productos item: list) clone.add(item.clone()); 
    return clone; 
} 

对于上面的方法来工作,你必须让你PRODUCTOS对象实现Cloneable接口并覆盖clone()方法。如果需要的话,你可以在这里阅读这个过程:http://howtodoinjava.com/2012/11/08/a-guide-to-object-cloning-in-java/

相关问题