2010-04-07 17 views
13

Potrzebuję płytkiej kopii java ArrayList, czy powinienem użyć clone() lub powtórzyć iterację nad oryginalną listą i skopiować elementy do nowej tablicy array, która jest szybsza?ArrayList płytka kopia iterate lub klon()

+1

Podczas wpisywania pytania powinieneś zobaczyć listę powiązanych pytań, które pojawiły się (ta sama lista, którą widzisz w prawej dolnej kolumnie tej strony). Zerknąłeś w nich? Dlaczego te odpowiedzi nie były wystarczające? Proszę opracuj. – BalusC

+0

Przeszedłem przez okno. Nie było nic związanego z wydajnością pod względem iteratora ArrayList vs clone(). – tech20nn

Odpowiedz

9

Zastosowanie clone() lub użyj copy-konstruktor.

Konstruktor kopii dokonuje dodatkowej transformacji z przekazanego zbioru do tablicy, podczas gdy metoda clone() bezpośrednio korzysta z tablicy wewnętrznej.

Należy pamiętać, że clone() zwraca Object, więc musisz odrzucić do List.

+0

Dokładnie przyjrzałem się kodowi źródłowemu java.util.ArrayList i odkryłem, że klon() używa Array.copyof, który byłby znacznie bardziej wydajny niż pętla nad oryginałem ArrayList. public Object clone() {try { @SuppressWarnings ("niesprawdzone") ArrayList v = (ArrayList ) super.clone(); v.elementData = Arrays.copyOf (elementData, rozmiar); v.modCount = 0; return v; } catch (CloneNotSupportedException e) { // To nie powinno się zdarzyć, ponieważ jesteśmy Cloneable throw new InternalError(); } } – tech20nn

+1

Nie martwię się zbytnio o wydajność. Używanie clone() to ból; po prostu użyj konstruktora konwersji zgodnie z sugestią. –

+2

@ Kevin Bourrillion dlaczego myślisz, że używając 'clone()' jest ból? Wdrożenie 'clone()' oznacza ból, a nie używanie go. – Bozho

8

Zamiast powtarzać ręcznie, można użyć copy constructor.

Co do różnicy prędkości pomiędzy tym i korzystania clone():

  1. Nieważne
  2. Najprawdopodobniej istnieje żaden
  3. Czy punkt odniesienia dla konkretnej konfiguracji systemu i użyj sprawę
+0

@ Michael..Thanks. Sprawdziłem kod dla konstruktora kopii. Ma dodatkowy krok do zwrócenia kopii wewnętrznej struktury tablicowej, o czym wspomniał Bozho. publiczny ArrayList (Collection c) { elementData = c.toArray(); size = elementData.length; if (elementData.getClass()! = Object []. Class) elementData = Arrays.copyOf (elementData, size, Object []. Class); } – tech20nn

+0

Podoba mi się uniwersalny "powinienem zoptymalizować?" wzór myślowy –

-1

pytanie mówi shallowcopy nie deepcopy.Copying bezpośrednie odwołanie z jednego odniesienia do listy arraylist do innego będzie również działać right.Deep kopii zawiera kopię indywidualnych element w tablicy listy.

ArrayList<Integer> list=new ArrayList<Integer>(); 
list.add(3); 
ArrayList<Integer> list1=list; //shallow copy... 

Czy jest jakiś problem?

+2

To jest złe. Wszystko to sprawi, że w pamięci będą znajdować się dwa wskaźniki do jednego fizycznego obiektu 'ArrayList'. Dodanie 'Integer' do jednej listy powoduje, że' Integer' pojawia się również na drugiej liście. Nie tego chcemy. Płytka kopia powoduje, że obiekty leżące pod nią dzielą tę samą przestrzeń pamięci, ale listy mają oddzielne miejsce w pamięci. Więc jeśli zmodyfikujesz jedną "Integer", zostanie ona zmodyfikowana na obu listach. Ale jeśli dodasz "Integer" do jednej listy, nie pojawi się ona w drugiej. Głęboka kopia nie odzwierciedla żadnych zmian w ogóle na drugiej liście. – Antimonit