Ne ho uno di ArrayList<String>
cui vorrei restituire una copia. ArrayList
ha un metodo clone che ha la seguente firma:
public Object clone()
Dopo aver chiamato questo metodo, come posso ricollegare l'oggetto restituito ArrayList<String>
?
Ne ho uno di ArrayList<String>
cui vorrei restituire una copia. ArrayList
ha un metodo clone che ha la seguente firma:
public Object clone()
Dopo aver chiamato questo metodo, come posso ricollegare l'oggetto restituito ArrayList<String>
?
Risposte:
ArrayList newArrayList = (ArrayList) oldArrayList.clone();
ArrayList<String> newArrayList = (ArrayList<String>) oldArrayList.clone();
.
List<String>
invece ArrayList<String>
sul lato sinistro. Questo è il modo in cui le raccolte dovrebbero essere utilizzate la maggior parte del tempo.
Perché vorresti clonare? La creazione di un nuovo elenco di solito ha più senso.
List<String> strs;
...
List<String> newStrs = new ArrayList<>(strs);
Lavoro fatto.
ArrayList(Collection<? extends E> c)
significa che non importa quale tipo di elenco usi come argomento.
Questo è il codice che uso per questo:
ArrayList copy = new ArrayList (original.size());
Collections.copy(copy, original);
La speranza è utile per te
ArrayList
usareArrayList<YourObject>
ArrayList
costruttore?
Con Java 8 può essere clonato con un flusso.
import static java.util.stream.Collectors.toList;
...
List<AnObject> clone = myList.stream().collect(toList());
toCollection
potrebbe essere una scelta migliore.
Si noti che Object.clone () presenta alcuni problemi importanti e il suo utilizzo è sconsigliato nella maggior parte dei casi. Si prega di vedere l'articolo 11, da " Effective Java " di Joshua Bloch per una risposta completa. Credo che tu possa usare tranquillamente Object.clone () su array di tipi primitivi, ma a parte questo devi essere prudente sull'uso e l'override del clone. Probabilmente stai meglio definendo un costruttore di copie o un metodo factory statico che clona esplicitamente l'oggetto in base alla tua semantica.
Penso che questo dovrebbe fare il trucco usando l'API Collections:
Nota : il metodo di copia viene eseguito in tempo lineare.
//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());
Sembra che l'utilizzo copyList.addAll(original);
sia una buona alternativa
int
argomenti misteriosi . Non ho idea del perché tu voglia usare questo oscuro metodo statico invece di un buon vecchio addAll
.
Trovo che usando addAll funzioni bene.
ArrayList<String> copy = new ArrayList<String>();
copy.addAll(original);
vengono utilizzate le parentesi anziché la sintassi generica
new ArrayList<String>(original)
?
Se vuoi questo per essere in grado di restituire l'elenco in un getter, sarebbe meglio fare:
ImmutableList.copyOf(list);
Per clonare un'interfaccia generica come java.util.List
te dovrai solo lanciarla. ecco un esempio:
List list = new ArrayList();
List list2 = ((List) ( (ArrayList) list).clone());
È un po 'complicato, ma funziona, se sei limitato a restituire List
un'interfaccia, quindi chiunque dopo puoi implementare la tua lista quando vuole.
So che questa risposta è vicina alla risposta finale, ma la mia risposta risponde come fare tutto ciò mentre lavori con List
il genitore genericoArrayList
Prestare molta attenzione durante la clonazione di ArrayLists. La clonazione in Java è superficiale. Ciò significa che clonerà solo l'Arraylist stesso e non i suoi membri. Quindi, se si dispone di un ArrayList X1 e lo si clona in X2, qualsiasi cambiamento in X2 si manifesterà anche in X1 e viceversa. Quando clonerai genererai solo una nuova ArrayList con puntatori agli stessi elementi nell'originale.
List<String> shallowClonedList = new ArrayList<>(listOfStrings);
Tieni presente che questa è solo una copia superficiale, non una copia profonda, vale a dire. si ottiene un nuovo elenco, ma le voci sono le stesse. Questo non è un problema per semplici stringhe. Diventa più complicato quando le voci dell'elenco sono oggetti stessi.
Non sono un professionista di Java, ma ho lo stesso problema e ho provato a risolvere con questo metodo. (Suppone che T abbia un costruttore di copie).
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
classe di implementazione abbia un costruttore pubblico no-arg. Ad esempio, la List
s ritorna da Array.asList
, List.of
o List.subList
probabilmente no.