【问题标题】:How to copy elements from an ArrayList to another one NOT by reference?如何将元素从 ArrayList 复制到另一个不通过引用?
【发布时间】:2017-05-14 11:38:30
【问题描述】:

我正在尝试将每个元素从一个 ArrayList (av) 复制到另一个 (copia)。问题是它们是通过引用复制的,所以每当我对原始文件进行任何更改时,副本也会被修改。当然,这种行为是不想要的。这个方法应该怎么写?

public void copiarArrayList(ArrayList<Articulo_Venta> copia, ArrayList<Articulo_Venta> av){
    copia.clear();
    for (int i = 0; i < av.size(); i++) {
        copia.add(av.get(i));
    }
}

Articulo_Venta 具有以下字段:

int codigo;
String nombre;
float cantidad;

PS:我也试了下:

copia = new ArrayList<Articulo_Venta>(av);

但它的元素仍然指向原始的 ArrayList。

【问题讨论】:

    标签: java arraylist constructor pass-by-value


    【解决方案1】:

    你想要的是深拷贝。如果您的对象仅包含原始对象,您可以使用 clone(),否则最好的方法是手动执行:-

    在您的 Articulo_Venta 类中创建一个构造函数,该构造函数接受另一个 Articulo_Venta 对象并初始化成员变量。

    然后把代码改成:-

    public void copiarArrayList(ArrayList<Articulo_Venta> copia, ArrayList<Articulo_Venta> av){
            copia.clear();
            for (int i = 0; i < av.size(); i++) {
                copia.add(new Articulo_Venta(av.get(i)));
            }
    

    也在这里阅读 - how-do-you-make-a-deep-copy-of-an-object-in-java

    【讨论】:

    • 就是这样!这样做很烦人,但解决方案是将对象的每个字段单独复制到一个新对象中,并将其添加到新的 ArrayList 中。谢谢,新年快乐!
    • 你救了我的命 :)
    【解决方案2】:

    在添加对象之前克隆对象。例如,而不是newList.addAll(oldList);

    for(Articulo_Venta av : oldList) {
        newList.add(av.clone());
    }
    

    应该在 Articulo_Venta 中正确覆盖克隆。

    这就是你的做法。

    public class Articulo_Venta {
    
    String a;  //assuming you have these fields, then
    Date d;
    ...
    
    public Articulo_Venta clone(){
        Articulo_Venta  av = new Articulo_Venta();
        av.a = this.a.clone();
        av.d = this.d.clone();
        ...
        return av;
    }
    }
    

    【讨论】:

    • 但是如果 av 包含更多对其他对象的引用怎么办,不会全部克隆复制它们吗?
    • 尽量不要在Java中覆盖克隆:-stackoverflow.com/questions/270369/…
    • @MangatRaiModi 是的,我知道你不能克隆原语。这就是为什么我在示例中没有包含任何原语:P
    【解决方案3】:

    在您的类 Articulo_Venta 中创建一个新的构造函数。

    public Articulo_Venta(int codigo, String number, float candidad)
    {
      this.codigo = codigo;
      this.number = number;
      this.candidad = candidad;
    }
    
    public void copiarArrayList(List<Articulo_Venta> copia, List<Articulo_Venta> av)
    {
       av.stream().forEach(t -> {
         Articulo_Venta newObj = new Articulo_Venta(t.getCodigo(), t.getNumber(), t.getCandidad());
         copia.add(newObj);
       });
    }
    

    【讨论】:

    • 这也可以,但使用 Articulo_Venta 作为参数创建构造函数会更简单一些。
    猜你喜欢
    • 2018-07-21
    • 2017-12-30
    • 1970-01-01
    • 2010-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-07
    • 2014-03-18
    相关资源
    最近更新 更多