2009-11-25 15 views
19

Come si può fare?Java: Ordina una lista non modificabile

Ho provato a creare una nuova lista vuota, quindi a copiare gli elementi della lista non modificabile, ma sto ricevendo un errore di operazione non supportato.

Qualsiasi aiuto è apprezzato.

+2

Puoi mostrare il codice che stai utilizzando per copiare l'elenco? – theycallmemorty

risposta

19

Stai creando una lista vuota utilizzando Collections.emptyList()? Se è così, anche questa è una lista non modificabile e quella potrebbe essere la fonte del tuo problema.

Creare un nuovo elenco utilizzando la funzione di costruzione per l'implementazione Elenco, ad esempio new ArrayList(). È possibile passare l'elenco originale nel costruttore oppure utilizzare il metodo addAll().

34
List unmodifiableList = Collections.unmodifiableList(list); 

    List newList = new ArrayList(unmodifiableList); 

    Collections.sort(newList); 

Il costruttore di ArrayList prende un elenco esistente, legge i suoi elementi (senza modificarli!), E li aggiunge la nuova lista.

0

Dovrebbe funzionare come descritto. Gli elementi di un Elenco non modificabile non sono immodificabili. Ovviamente non è possibile ordinare un Elenco non modificabile, poiché deve essere riscritto con operazioni di aggiunta ed eliminazione e non è consentito.

Immagino l'errore è da qualche altra parte, migliore sarebbe quella di mostrare il codice :)

38

FWIW, con google-collections si tratta di un one-liner:

List<Foo> sorted = Ordering.natural().sortedCopy(unmodifiableList); 
+2

Sembra pubblicità ... Mi piace. – whiskeysierra

+1

Solo perché c'è la parola "google"? : p Comunque. È una pubblicità. Uno che è probabilmente non pagato. –

0

io risponderò alla tua seconda domanda:

Non è possibile aggiungere all'elenco "taskListModifiable" perché è un elenco "non modificabile", che in Java significa che è immutabile. Un elenco o una raccolta non modificabile/immutabile di qualsiasi tipo non può essere modificato direttamente in alcun modo: non è possibile aggiungere elementi ad esso, rimuovere elementi da esso o modificare riferimenti ad elementi esistenti.

Si noti che gli elementi esistenti nell'elenco/raccolta possono essere modificati se sono essi stessi modificabili, ma i riferimenti ad essi dall'elenco non possono essere modificati. Cioè, fino a quando l'elenco non sarà completamente fuori portata ed è stato eliminato dalla garbage collection, l'elenco non modificabile conterrà sempre gli stessi riferimenti.

Ora, nel tuo caso, Collections.emptyList() restituisce un elenco non modificabile EMPTY. In realtà, è sempre la stessa istanza poiché è immutabile e sempre vuota. Non è possibile aggiungerlo a causa della regola che non è possibile espandere un elenco immutabile (aggiunto a). Poiché è vuoto, non c'è nulla che possa essere modificato.

Dovrei aggiungere per rendere ancora più chiaro che Collection.emptyList() non crea una lista vuota. Restituisce solo un riferimento a un'istanza dell'elenco singleton.

+2

immodificabile * NON È * immutabile in Java !!Se crei un elenco non modificabile dopo 'list1', e poi aggiungi/rimuovi oggetti a' list1', l'elenco non modificabile rifletterà le modifiche. –

+0

Questo vale per qualsiasi lingua in cui la raccolta non modificabile avvolge semplicemente l'altra raccolta (ad esempio non crea una copia sicura), non solo Java. Stai parlando di mantenere un riferimento all'oggetto avvolto e di cambiarlo. Tuttavia, stavo facendo un commento (cosa che non potevo fare) ad un'altra risposta in cui chiedevano perché non potevano cambiare la specifica taskListModifiable dove è stata creata con questo: taskListModifiable = Collections.emptyList(). Infatti, in tutti i casi, questo è immutabile perché emptyList() restituisce una lista vuota, Singleton, immutabile. –

+0

@True Soft: sì, hai ragione, la lista di supporto all'interno di alcuni elenchi "non modificabili" è in realtà modificabile. È vero che non è rigorosamente immutabile e che non puoi necessariamente trattarlo come tale. Tuttavia, in pratica è spesso possibile, se si crea la lista, quindi renderla non modificabile, quindi buttare il puntatore iniziale alla lista. –

4

In Java 8, è possibile utilizzare l'API degli stream. Ad esempio:

List<?> sortedList = unsortedList.stream().sorted().collect(Collectors.toList());