Mam ArrayList<String>
kopię, którą chciałbym zwrócić. ArrayList
ma metodę klonowania, która ma następujący podpis:
public Object clone()
Po wywołaniu tej metody, jak mam rzutować zwrócony Object z powrotem do ArrayList<String>
?
Mam ArrayList<String>
kopię, którą chciałbym zwrócić. ArrayList
ma metodę klonowania, która ma następujący podpis:
public Object clone()
Po wywołaniu tej metody, jak mam rzutować zwrócony Object z powrotem do ArrayList<String>
?
Odpowiedzi:
ArrayList newArrayList = (ArrayList) oldArrayList.clone();
ArrayList<String> newArrayList = (ArrayList<String>) oldArrayList.clone();
.
List<String>
zamiast ArrayList<String>
po lewej stronie. W ten sposób kolekcje powinny być używane przez większość czasu.
Dlaczego chcesz klonować? Tworzenie nowej listy ma zwykle większy sens.
List<String> strs;
...
List<String> newStrs = new ArrayList<>(strs);
Zadanie wykonane.
ArrayList(Collection<? extends E> c)
oznacza, że nie ma znaczenia, jakiego rodzaju listy użyjesz jako argumentu.
Oto kod, którego używam do tego:
ArrayList copy = new ArrayList (original.size());
Collections.copy(copy, original);
Nadzieja jest dla ciebie przydatna
ArrayList
używaćArrayList<YourObject>
ArrayList
konstruktora?
W Javie 8 można go sklonować za pomocą strumienia.
import static java.util.stream.Collectors.toList;
...
List<AnObject> clone = myList.stream().collect(toList());
toCollection
może być lepszym wyborem.
Należy pamiętać, że Object.clone () ma poważne problemy i odradza się jego używanie w większości przypadków. Pełną odpowiedź można znaleźć w punkcie 11 książki „ Efektywna Java ” Joshuy Blocha. Uważam, że możesz bezpiecznie używać Object.clone () na tablicach typów prymitywnych, ale poza tym musisz rozsądnie używać i nadpisywać clone. Prawdopodobnie lepiej będzie zdefiniować konstruktor kopiujący lub statyczną metodę fabryki, która jawnie klonuje obiekt zgodnie z twoją semantyką.
Myślę, że to powinno załatwić sprawę przy użyciu Collection API:
Uwaga : metoda kopiowania działa w czasie liniowym.
//assume oldList exists and has data in it.
List<String> newList = new ArrayList<String>();
Collections.copy(newList, oldList);
List<MySerializableObject> copyList = new ArrayList<>(mMySerializableObjects.size());
Wydaje się, że używanie copyList.addAll(original);
jest dobrą alternatywą
int
argumentów. Nie mam pojęcia, dlaczego chcesz użyć tej mało znanej metody statycznej zamiast starej, dobrej addAll
.
Uważam, że użycie addAll działa dobrze.
ArrayList<String> copy = new ArrayList<String>();
copy.addAll(original);
zamiast generycznej składni używane są nawiasy
new ArrayList<String>(original)
?
Jeśli chcesz tego, aby móc zwrócić Listę w getterze, lepiej byłoby zrobić:
ImmutableList.copyOf(list);
Aby sklonować ogólny interfejs, taki jak java.util.List
ty, wystarczy go przesłać. oto przykład:
List list = new ArrayList();
List list2 = ((List) ( (ArrayList) list).clone());
Jest to trochę trudne, ale działa, jeśli jesteś ograniczony do zwrócenia pliku List
interfejsu, więc każdy może zaimplementować twoją listę, kiedy tylko zechce.
Wiem, że ta odpowiedź jest bliska ostatecznej odpowiedzi, ale moja odpowiedź odpowiada, jak to wszystko zrobić, gdy pracujesz z List
- generycznym rodzicem - nieArrayList
Zachowaj ostrożność podczas klonowania ArrayLists. Klonowanie w Javie jest płytkie. Oznacza to, że sklonuje tylko samego Arraylist, a nie jego członków. Więc jeśli masz ArrayList X1 i sklonujesz ją do X2, każda zmiana w X2 będzie również widoczna w X1 i odwrotnie. Podczas klonowania wygenerujesz tylko nową ArrayList ze wskaźnikami do tych samych elementów w oryginale.
List<String> shallowClonedList = new ArrayList<>(listOfStrings);
Należy pamiętać, że jest to tylko płytka, a nie głęboka kopia, tj. otrzymasz nową listę, ale wpisy są takie same. Nie stanowi to problemu dla prostych strun. Get jest trudniejszy, gdy pozycje listy same w sobie są obiektami.
Nie jestem specjalistą od Java, ale mam ten sam problem i próbowałem rozwiązać tą metodą. (Zakłada się, że T ma konstruktora kopiującego).
public static <T extends Object> List<T> clone(List<T> list) {
try {
List<T> c = list.getClass().newInstance();
for(T t: list) {
T copy = (T) t.getClass().getDeclaredConstructor(t.getclass()).newInstance(t);
c.add(copy);
}
return c;
} catch(Exception e) {
throw new RuntimeException("List cloning unsupported",e);
}
}
List
klasa implementacji ma publiczny konstruktor bez argumentów. Na przykład, List
s powroty przez Array.asList
, List.of
lub List.subList
prawdopodobnie nie.