2015-08-19 3 views
5

Ho creato due elenchi dallo stesso array e ne ho ordinato uno. Quando ho provato a cambiare una lista, anche l'altra lista è stata aggiornata.Creato due elenchi dallo stesso array, modificando un elenco, cambia l'altro

List<Integer> list = Arrays.asList(ar); 
List<Integer> sorted = Arrays.asList(ar); 
Collections.sort(sorted); 
list.set(0,10000000); //changes sorted also 

Mi ci è voluto un po 'di tempo, sotto il codice citato ha funzionato.

List<Integer> sorted = new ArrayList<Integer>(Arrays.asList(ar));

Voglio sapere perché il mio primo approccio non ha funzionato? Ho creato due elenchi separati, perché i cambiamenti si stanno verificando in entrambi. In che modo java assegna valori alle variabili qui?

+0

'list' e' sorted' stanno puntando allo stesso array, vero? – Andrew

+1

@AndrewTobilko: ma ha solo un elenco. Vado a votare questo come una domanda interessante. –

+0

Sono un po 'sorpreso dal fatto che questa sembra essere la prima volta che viene posta questa domanda su SO dal momento che il "problema" è vecchio come lo stesso 'Arrays' api (java 1.2). E dubito che tutti abbiano letto (e capito) la javadoc fino ad ora ... –

risposta

11

Dalla documentazione Java per Arrays.asList:

Restituisce un elenco di dimensioni fisse sostenuto dalla matrice specificata. (Le modifiche all'elenco restituito "write through" all'array.) Questo metodo funge da ponte tra API basate su array e raccolte, in combinazione con Collection.toArray(). L'elenco restituito è serializzabile e implementa RandomAccess.

Quindi, quando si cambia qualcosa nella lista, "scrive attraverso" alla matrice sottostante, ar, che è anche la matrice sottostante ordinato, in modo che il cambiamento si riflette nella ordinato pure.

Inoltre, il codice per asList è:

public static <T> List<T> asList(T... a) { 
    return new ArrayList<T>(a); 
} 

Questo è java.util.Arrays.ArrayList, che ha la seguente definizione:

ArrayList(E[] array) { 
    a = Objects.requireNonNull(array); 
} 

Ciò che è importante è che a non viene copiato, è l'originale array. La classe java.util.ArrayList ha il seguente costruttore

public ArrayList(Collection<? extends E> c) { 
    elementData = c.toArray(); 
    size = elementData.length; 
    // c.toArray might (incorrectly) not return Object[] (see 6260652) 
    if (elementData.getClass() != Object[].class) 
     elementData = Arrays.copyOf(elementData, size, Object[].class); 
} 

così nel costruttore java.util.ArrayList, noi creare copie di ogni elemento, e in java.util.Arrays.ArrayList, non lo facciamo.

+2

Per favore, non confondere 'java.util.Arrays.ArrayList' e' java.util.ArrayList'. Il comportamento non è cambiato in Java 8. – Holger

+0

@Holger, grazie! Ho aggiornato il mio post originale per includere questo punto. – Sunde

1

Array ha le proprie implementazioni di ArrayList che non fanno una copia di matrice da toList

1

Una lista è una collezione di oggetti, ed entrambi lista sono raccolte degli stessi oggetti. L'istruzione set modifica un oggetto e l'oggetto è condiviso da entrambi gli elenchi.

Non capisco perché la seconda versione funzioni.