2016-06-17 6 views
0

Я пытаюсь скопировать содержимое ArrayList в другое и изменить содержимое копии. Я не хочу, чтобы это отражалось в оригинале.Почему модификация в копии Arraylist, изменяет оригинал?

Я проверил SO и внес соответствующие изменения, по-прежнему та же проблема. Может кто-нибудь помочь? Я делюсь код ниже:

private ArrayList<CustVoiceListObject> FilterApprovedWorkFromList() { 

     ArrayList<CustVoiceListObject> arrayListCopy = new ArrayList<>(arrayListCustVoice); 

      for(int i =0; i<arrayListCopy.get(position).getPackageArray().size();i++) 
      { 
       if(!arrayListCopy.get(position).getPackageArray().get(i).getPackageApproved().equals("Y")) 
       { 
        arrayListCopy.get(position).getPackageArray().remove(i); 
        i--; 
       } 
      } 
     return arrayListCopy; 
    } 

Во время отладки, когда он собирается вернуться, проверить оригинальный ArrayList arrayListCustVoice, но это также модифицирован аналогично arrayListCopy

Что мне не хватает?

UPDATE [После предложения] [Это вопросы, следовательно, не дублировать!]

Это мой модифицированный код:

private ArrayList<CustVoiceListObject> FilterApprovedWorkFromList() { 

     ArrayList<CustVoiceListObject> arrayListCopy = (ArrayList<CustVoiceListObject>) arrayListCustVoice.clone(); 

      for(int i =0; i<arrayListCopy.get(position).getPackageArray().size();i++) 
      { 
       if(!arrayListCopy.get(position).getPackageArray().get(i).getPackageApproved().equals("Y")) 
       { 
        arrayListCopy.get(position).getPackageArray().remove(i); 
        i--; 
       } 
      } 
     return arrayListCopy; 
    } 

На самом деле я реализованного Cloneable к моему оригинальному классу, по-прежнему Я столкнулся с той же проблемой.

Update 2 [Исследования Заключение]

Я наткнулся на этот link

В моем случае есть 2 класса. Второй является подмножеством первого. Приклеивание ниже:

public class CustVoiceListObject implements Cloneable { 

    private String txtSource, txtCustComment, txtCustOk, txtRepeat; 

    private int numberOfPackages, complaintSerial; 

    private ArrayList<CustomerVoicePackageListObject> packageArray; 

    private Double totalAmount; 

    //getters & setters & constructors 

    @Override 
    protected Object clone() throws CloneNotSupportedException { 
     return super.clone(); 
    } 


} 

Класс 2:

public class CustomerVoicePackageListObject implements Cloneable { 

    public String packageCategory; 
    public String packageName; 
    public String partUsageFlag; 
    public String laborUsageFlag; 
    public String status; 
    public String isApproved; 

//getters & setters & constructors 

    @Override 
    protected Object clone() throws CloneNotSupportedException { 
     return super.clone(); 
    } 

} 

.clone() необходимо связать с clone() из класса, а не в другом месте. И если это правильно, это спровоцирует меры для устранения исключения в соответствии с моим внедрением clone() в каждом отдельном классе.

Так это то, что я сделал, модифицированный, что цикл к этому:

private CustVoiceListObject FilterApprovedWorkFromList() { 

//Observe the change here. It's no more ArrayList, it's Class type 
     CustVoiceListObject arrayListCopy = null; 
     try { 
      arrayListCopy = (CustVoiceListObject) arrayListCustVoice.get(position).clone(); 
     } catch (CloneNotSupportedException e) { 
      e.printStackTrace(); 
     } 

     for(int i =0; i<arrayListCopy.getPackageArray().size();i++) 
      { 
       if(!arrayListCopy.getPackageArray().get(i).getPackageApproved().equals("Y")) 
       { 
        arrayListCopy.getPackageArray().remove(i); //this is ArrayList<ClassType>. Nested class objects. 
        arrayListCopy.setTxtCustOk("OKOK"); //within the class 
        i--; 
       } 
      } 
     return arrayListCopy; 
    } 

В результате был изменяется в пределах packageArray отражение в обоих (провал) НО, изменения в txtCustOk в пределах базового класса, изменен в копии, а не в оригинале (успех). Это означает, что проблема заключается в клонировании с ArrayList

Так глубокого клонирования требует удовлетворения следующих правил:

1.No необходимо отдельно скопировать примитивы.

2. Все классы-члены в исходном классе должны поддерживать клонирование, а метод clone исходного класса в контексте должен вызывать super.clone() для всех классов-членов.

3. Если какой-либо класс-член не поддерживает клонирование, а затем в методе clone, необходимо создать новый экземпляр этого класса-члена и скопировать все его атрибуты по одному новому объекту класса-члена. Этот новый член объект класса будет установлен в клонированный объект.

Итак, моя цель - избавиться от ArrayList и сменить эти элементы на этот класс. Это болезненно. Ищете легкую альтернативу.

+0

заменить эту строку и проверить ArrayList arrayListCopy = новый ArrayList <> (arrayListCustVoice); by ArrayList arrayListCopy = arrayListCustVoice; – Vickyexpert

+0

Это была моя первая попытка. Не смогли. –

+0

Я не рассматриваю категоризацию этого вопроса как дубликат, apt. Ни одно из этих решений не работает здесь. –

ответ

1

Проблема заключается в том, что ваши исходные элементы ArrayList являются ссылочными значениями, поэтому вы просто копируете ссылки на эти объекты, но не сами объекты (которые, как представляется, являются еще одним видом массивов).

Обратите внимание на вопрос this, который по сути имеет дело с таким же видом проблемы.

+0

Забыл упомянуть, что это связано с JAVA. Концепция, конечно же, та же. –

+0

Другими словами: один и тот же объект помещен в оба списка, и изменение этого объекта будет видно в обоих списках. Возможно, сам объект должен быть клонирован, или при изменении нового объекта следует заменить исходный объект. –

0

Операция копирования скопировала исходный список, но не элементы списка.

То есть, если oldList имел следующие объекты: Person

oldList: John, Jane, Jude, Joe

И вы скопировали oldList в newList:

oldList: John, Jane, Jude, Joe
newList: John, Jane, Jude, Joe

И затем удаляется John из newList:

oldList: John, Jane, Jude, Joe
newList: Jane, Jude, Joe

вы можете увидеть, что они являются двумя отдельными списками. Но вы не изменение списков, вы меняете объекты внутри список. Если имя Joe «S переоделся в Jim, вы бы:

oldList: John, Jane, Jude, Jim
newList: Jane, Jude, Jim

Вы только сделали то, называется «мелкой» копией. Вы хотите сделать «глубокую» копию, как показано на рисунке here.


Редактировать (в "Update 2" в вопросе)

Ваши исследования не идут достаточно далеко, я боюсь. В вашем (новый) Класс 1:

public class CustVoiceListObject implements Cloneable { 

    // ints, Doubles, Strings 

    private ArrayList<CustomerVoicePackageListObject> packageArray; 

    //getters & setters & constructors 

    @Override 
    protected Object clone() throws CloneNotSupportedException { 
     return super.clone(); 
    } 
} 

вы просто вернулись super.clone() - выпускающего Java сделать всю работу за вас. Это в основном делает мелкую копию, которая вызывает все ваши проблемы! Вы могли бы также не сделать объект ICloneable. Что вы пропустили, так это то, что int s, Double s и даже String s уже успешно копируются, поэтому вам не нужно клонировать их. Но ArrayLists сделать не клон, так что вам нужно, чтобы помочь ему вместе:

@Override 
protected Object clone() throws CloneNotSupportedException { 
    // First copy the easy stuff 
    CustomerVoiceListObject cvlo = (CustomerVoiceListObject)super.clone(); 

    cvlo.packageArray = new ArrayList<CustomerVoicePackageListObject>(packageArray.size()); // Make sure it's the right size 

    for (CustomerVoicePackageListObject cvplo: packageArray) { 
     cvlo.packageArray.add(cvplo.clone()); 
    } // for 
    return cvlo; 
} // clone() 
+0

Я сделал то же самое. У вас есть ссылка на Java? –

+0

Я обновил свой ответ с другой ссылкой для Java - хотя это требует, чтобы ваш класс реализовал интерфейс 'ICloneable' –

+0

. Проверьте обновление, которое я добавил, и дайте знать –

Смежные вопросы