Модераторы: LSD, AntonSaburov

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Копирование ArrayList 
V
    Опции темы
Reptor
Дата 1.7.2008, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1213
Регистрация: 29.12.2004

Репутация: нет
Всего: 0



Проблема вот в чём:

есть какойто список private 

Код

ArrayList<X> list       = new ArrayList<X>();


Если одному листу присваивать такой же лист т о при изменении одного меняется и 2-ой лист так как копируется не содержимое а просто ссылка на объект - это если я правильно понял. Так а как сделать что б создавался абсолютно новый лист.

Делаю так и всеровно не выходит. Меняю старый, меняется и новый и наоборот

Код

this.list        = new ArrayList<X>(list);


Как это побороть?
PM MAIL ICQ   Вверх
LSD
Дата 1.7.2008, 16:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



clone()
(но объекты в новом листе будут те же самые)


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Reptor
Дата 1.7.2008, 16:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1213
Регистрация: 29.12.2004

Репутация: нет
Всего: 0





this.list = ( ArrayList<X>)list.clone();

не помогло. Всеровно если менять объекты одного листа то в 2-ом они тоже меняются, ну и наоборот
PM MAIL ICQ   Вверх
cube
Дата 1.7.2008, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 11.4.2007

Репутация: 2
Всего: 3



Цитата(Reptor @ 1.7.2008,  16:53)
this.list = ( ArrayList<X>)list.clone();

не помогло. Всеровно если менять объекты одного листа то в 2-ом они тоже меняются, ну и наоборот

тогда ты должен у каждого объекта Х в ArrayList'e использовать clone()

PM MAIL   Вверх
Reptor
Дата 1.7.2008, 17:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1213
Регистрация: 29.12.2004

Репутация: нет
Всего: 0



так что выходит надо итератором проходить по листу и делать клоне каждого объекта а потом this.list.add( Object.clone() ) ?? 

мне кажется что такое копирование больших листов повешает всё приложение

Это сообщение отредактировал(а) Reptor - 1.7.2008, 17:23
PM MAIL ICQ   Вверх
Orange
Дата 1.7.2008, 18:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 129
Регистрация: 6.9.2004
Где: Russia, Moscow

Репутация: 4
Всего: 5



а Collections.copy(list1, list2) не подойдёт?

(ну или делай свою реализацию cloneable)

Это сообщение отредактировал(а) Orange - 1.7.2008, 18:19
--------------------
Пару дней назад я познакомился с мальчиком......
PM MAIL ICQ   Вверх
Reptor
Дата 1.7.2008, 18:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1213
Регистрация: 29.12.2004

Репутация: нет
Всего: 0



Orange, не знаю подойдёт или нет... не пробовал.. я так понимаю это с common-collections.. надо посмотреть как там реализовано..

Это сообщение отредактировал(а) Reptor - 1.7.2008, 18:22
PM MAIL ICQ   Вверх
Orange
Дата 1.7.2008, 18:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 129
Регистрация: 6.9.2004
Где: Russia, Moscow

Репутация: 4
Всего: 5



Цитата(Reptor @ 1.7.2008,  18:16)
Orange, не знаю подойдёт или нет... я так понимаю это с common-collections.. надо посмотреть как там реализовано..

И да, у Эккеля было по поводу глубокого клонирования достаточно подробно описанно
--------------------
Пару дней назад я познакомился с мальчиком......
PM MAIL ICQ   Вверх
Reptor
Дата 1.7.2008, 18:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1213
Регистрация: 29.12.2004

Репутация: нет
Всего: 0



   
у меня при таком подходе ошибка

    
Код

    Collections.copy(this.list, list);


Exception occurred during event dispatching:
java.lang.IndexOutOfBoundsException: Source does not fit in dest

PM MAIL ICQ   Вверх
ivg
Дата 1.7.2008, 19:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Autonomous R&D
**


Профиль
Группа: Участник
Сообщений: 686
Регистрация: 8.2.2006
Где: Екатеринбург

Репутация: 33
Всего: 81



Цитата(Reptor @  1.7.2008,  19:33 Найти цитируемый пост)
Делаю так и всеровно не выходит. Меняю старый, меняется и новый и наоборот

А покажите как вы это делаете?
PM MAIL   Вверх
powerOn
Дата 1.7.2008, 22:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 47
Всего: 159



Цитата(Reptor @  1.7.2008,  19:26 Найти цитируемый пост)
Exception occurred during event dispatching:
java.lang.IndexOutOfBoundsException: Source does not fit in dest 


если посмотреть в исходники Collections.sort, то можно узнать много интересного:

Код

public static <T> void copy(List<? super T> dest, List<? extends T> src) {
        int srcSize = src.size();
        if (srcSize > dest.size())
            throw new IndexOutOfBoundsException("Source does not fit in dest");

        if (srcSize < COPY_THRESHOLD ||
            (src instanceof RandomAccess && dest instanceof RandomAccess)) {
            for (int i=0; i<srcSize; i++)
                dest.set(i, src.get(i));
        } else {
            ListIterator<? super T> di=dest.listIterator();
        ListIterator<? extends T> si=src.listIterator();
            for (int i=0; i<srcSize; i++) {
                di.next();
                di.set(si.next());
            }
        }
    }


тот лист, в который будет вестись копирование, уже должен содержать элементов не меньше, чем в листе-источнике. Но, честно говоря, зачем такое условие нужно я плохо себе представляю.



--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
Platon
Дата 1.7.2008, 22:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1801
Регистрация: 25.4.2006

Репутация: 16
Всего: 40



На сколько могу судить по исходному коду Collections.copy тоже не подходит, он копирует только ссылки.
PM MAIL ICQ   Вверх
powerOn
Дата 1.7.2008, 23:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 47
Всего: 159



Цитата(Platon @  1.7.2008,  23:23 Найти цитируемый пост)
он копирует только ссылки. 

это точно.


--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
Kangaroo
Дата 2.7.2008, 00:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


AA - Aussie Animal
****


Профиль
Группа: Участник Клуба
Сообщений: 2042
Регистрация: 7.10.2006
Где: US

Репутация: 21
Всего: 104



Цитата(powerOn @  1.7.2008,  22:02 Найти цитируемый пост)
Но, честно говоря, зачем такое условие нужно я плохо себе представляю.

Наверное, чтобы максимально оптимизировать следующий за этой проверкой код.


--------------------
Lost....
PM MAIL MSN   Вверх
COVD
Дата 2.7.2008, 01:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 17
Всего: 43



Цитата

так что выходит надо итератором проходить по листу и делать клоне каждого объекта а потом this.list.add( Object.clone() ) ?? 


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

Цитата

мне кажется что такое копирование больших листов повешает всё приложение


Есть программистская заповедь: "Не плодите сущности".  Из которой следует, что вам лучше поискать другое решение. 
PM MAIL   Вверх
LSD
Дата 2.7.2008, 10:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Нет ни одного готового класса который мог бы осуществлять глубокое клонирование, потому что у Object метод clone() не public.

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


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Reptor
Дата 2.7.2008, 10:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1213
Регистрация: 29.12.2004

Репутация: нет
Всего: 0



ехххх, да незадачка. 


мне удивительно почему не помагает   

Код

class X{
.....
}

class X2{

   private ArrayList<X> list   = new ArrayList<X>();
   
   public X2(ArrayList<X> list){
               this.list =  new ArrayList<X>(list)
   }
}



вроде ж как через new..


PM MAIL ICQ   Вверх
LSD
Дата 2.7.2008, 11:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



new создает новый ArrayList и копирует туда ссылки на объекты из исходной коллекции.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Reptor
Дата 2.7.2008, 11:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1213
Регистрация: 29.12.2004

Репутация: нет
Всего: 0



попробую конечно через итераторы но думаю что ничего хорошего из этого не выйдет. 


LSD,  а как это через сериализацию?

Добавлено @ 11:55
ого так это ж ещё надо будет создавать каждый объект что в листе заново.... ведь если их просто переписать всеровно ссылки та останутся на старые...

не это не реально, это все переменные объекта надо будет достать и заново записать в новый объект, мало того что объектов не мало в листе так ещё и у объекта много всего...

Это сообщение отредактировал(а) Reptor - 2.7.2008, 11:56
PM MAIL ICQ   Вверх
Platon
Дата 2.7.2008, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1801
Регистрация: 25.4.2006

Репутация: 16
Всего: 40



Reptor, ну, а что сделать? Ты такие условия ставишь. Или смирись, или ищи как обойтись только ссылками на объекты.
PM MAIL ICQ   Вверх
Reptor
Дата 2.7.2008, 13:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1213
Регистрация: 29.12.2004

Репутация: нет
Всего: 0



Platon,  ну а как обойтись ссылками... не как не выйдет так как они то должны быть независимы а так меняеш один меняется 2-ой...   smile 
PM MAIL ICQ   Вверх
LSD
Дата 2.7.2008, 13:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(Reptor @  2.7.2008,  12:48 Найти цитируемый пост)
LSD,  а как это через сериализацию?

Да практически как гланды удалять через ж smile 
Код

  public static Object serialClone(Serializable s)
  {
    try
    {
      ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
      ObjectOutputStream objectOut = new ObjectOutputStream(byteOut);
      objectOut.writeObject(s);
      objectOut.close();

      ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
      ObjectInputStream objectIn = new ObjectInputStream(byteIn);
      Object copy = objectIn.readObject();
      objectIn.close();
      return copy;
    }
    catch(IOException e)
    {
      return null;// mustn't happend
    }
    catch(ClassNotFoundException e)
    {
      return null;// mustn't happend
    }
  }

  public static void main(String[] args) throws Exception
  {
    StringBuilder buffer = new StringBuilder("aaa");
    ArrayList<StringBuilder> list  = new ArrayList<StringBuilder>();
    list.add(buffer);

    ArrayList<StringBuilder> copy1  = (ArrayList<StringBuilder>) list.clone();
    ArrayList<StringBuilder> copy2  = (ArrayList<StringBuilder>) serialClone(list);

    System.out.println("list  = " + list);
    System.out.println("copy1 = " + copy1);
    System.out.println("copy2 = " + copy2);

    System.out.println("Changing...");
    buffer.append("bbbb");
    list.add(new StringBuilder("zzz"));

    System.out.println("list  = " + list);
    System.out.println("copy1 = " + copy1);
    System.out.println("copy2 = " + copy2);
  }

только учти, что это штука не быстрая и глубокое клонирование будет работать быстрее.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Reptor
Дата 2.7.2008, 14:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1213
Регистрация: 29.12.2004

Репутация: нет
Всего: 0



Цитата

что это штука не быстрая и глубокое клонирование будет работать быстрее


я не совсем понимаю что имеется в виду под глубоким копированием? почему глубоким?
PM MAIL ICQ   Вверх
dorogoyIV
Дата 2.7.2008, 14:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1503
Регистрация: 26.3.2007

Репутация: 3
Всего: 46



Цитата(Reptor @  2.7.2008,  14:05 Найти цитируемый пост)
я не совсем понимаю что имеется в виду под глубоким копированием? почему глубоким?

имеется ввиду:
глубокое клонирование - копирование всего массива с такими же объектами, только новыми
поверхностное клонирование - копирование всего массива с теми же ссылками (сам массив новый)

 smile  тоже наверное не очень понятно пояснил  smile 

Это сообщение отредактировал(а) dorogoyIV - 2.7.2008, 14:44
PM MAIL   Вверх
Reptor
Дата 2.7.2008, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1213
Регистрация: 29.12.2004

Репутация: нет
Всего: 0



dorogoyIV,  всё я понял..  smile  

всем огромное спасибо... 

надо будет попробовать сделать 2 варианта.
PM MAIL ICQ   Вверх
Reptor
Дата 3.7.2008, 11:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1213
Регистрация: 29.12.2004

Репутация: нет
Всего: 0



LSD,  смотри я немножко поменял то что ты прислал и у меня что то не вышло 

Код


import java.util.*;
import java.io.*;

public class zz {
    
     public static Object serialClone(Serializable s)    
      {    
        try    
        {    
          ByteArrayOutputStream byteOut = new ByteArrayOutputStream();    
          ObjectOutputStream objectOut = new ObjectOutputStream(byteOut);    
          objectOut.writeObject(s);    
          objectOut.close();    
          ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());    
          ObjectInputStream objectIn = new ObjectInputStream(byteIn);    
          Object copy = objectIn.readObject();    
          objectIn.close();    
          return copy;    
        }    
        catch(IOException e)
        {    
            return null;// mustn't happend    
          }    
          catch(ClassNotFoundException e)    
          {    
            return null;// mustn't happend    
          }    
        }
     
     public static void main(String[] args) throws Exception    
      {    
        StringBuilder buffer = new StringBuilder("aaa");    
        ArrayList<StringBuilder> list  = new ArrayList<StringBuilder>();    
        list.add(buffer);    
        ArrayList<StringBuilder> copy1  = (ArrayList<StringBuilder>) list.clone();    
        ArrayList<StringBuilder> copy2  = (ArrayList<StringBuilder>) zz.serialClone(list);    
        System.out.println("list  = " + list);    
        System.out.println("copy1 = " + copy1);    
        System.out.println("copy2 = " + copy2);    
        System.out.println("Changing...");    
        buffer.append("bbbb");    
        list.add(new StringBuilder("zzz"));
       
        copy1.get(0).append("ddd");
        copy2.get(0).append("hello");
        
        System.out.println("list  = " + list);    
        System.out.println("copy1 = " + copy1);    
        System.out.println("copy2 = " + copy2);    
        
        
        ArrayList<dd> listDD  = new ArrayList<dd>();    
        listDD.add(new dd(1));
        listDD.add(new dd(2));
        listDD.add(new dd(3));
        listDD.add(new dd(4));
        listDD.add(new dd(5));
        
        ArrayList<dd> copy1_2  = (ArrayList<dd>) listDD.clone();    
        ArrayList<dd> copy2_2  = (ArrayList<dd>) zz.serialClone(listDD);    
        
        
        System.out.println("list  = " + listDD);    
        System.out.println("copy1 = " + copy1_2);    
        System.out.println("copy2 = " + copy2_2);    
        
      }
}


и вот класс экземпляры которого в листе 

Код

public class dd{
    private int a =0;
    
    public dd(int a){
        this.a = a;            
    }
    
    public int  getA(){
        return a;
    }
    
    public void setA(int a){
        this.a = a;
    }
}



и вот вывод 

list  = [aaa]
copy1 = [aaa]
copy2 = [aaa]

Changing...
list  = [aaabbbbddd, zzz]
copy1 = [aaabbbbddd]
copy2 = [aaahello]


list  = [dd@1632c2d, dd@d70d7a, dd@b5f53a, dd@1f6f0bf, dd@137c60d]
copy1 = [dd@1632c2d, dd@d70d7a, dd@b5f53a, dd@1f6f0bf, dd@137c60d]
copy2 = null

почему то на  ArrayList<dd> copy2_2  = (ArrayList<dd>) zz.serialClone(listDD);     не сработало  copy2 = null ?

Может что то с классом не так?

а так всё хорошо работает а с собственным классом не хочет.

Добавлено @ 11:08 

о понял надо ж
Код

 implements Serializable


Это сообщение отредактировал(а) Reptor - 3.7.2008, 11:09
PM MAIL ICQ   Вверх
Reptor
Дата 15.7.2008, 17:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1213
Регистрация: 29.12.2004

Репутация: нет
Всего: 0



у меня ещё такой вопрос по поводу сеарилизацыи

если у меня в классе есть внутрений класс то что б он тоже сеарилизовался надо у него тоже указывать implements Serializable. Или у его родителя достаточно??

Просто в зависимости от того указываю я или нет то приложение как то по разному себя ведёт.
PM MAIL ICQ   Вверх
Platon
Дата 16.7.2008, 12:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1801
Регистрация: 25.4.2006

Репутация: 16
Всего: 40



Все классы должны быть сериализуемыми. 
PM MAIL ICQ   Вверх
Reptor
Дата 16.7.2008, 12:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1213
Регистрация: 29.12.2004

Репутация: нет
Всего: 0



Platon,  да я смотрю что если во внутренем классе не ставить  implements Serializable то основной совсем не клонируется
PM MAIL ICQ   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1286 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.