2009-11-25 13 views
19

¿Cómo se puede hacer esto?Java: ordenar una lista no modificable

He intentado crear una lista nueva y vacía, y luego copiar elementos de la lista no modificables, pero recibo un error de operación no compatible.

Cualquier ayuda es apreciada.

+2

¿Puede mostrar el código que está utilizando para copiar la lista? – theycallmemorty

Respuesta

19

¿Está creando una lista vacía usando Collections.emptyList()? Si es así, esa es una lista no modificable también y esa puede ser la fuente de su problema.

Cree una nueva lista usando el constructor para su implementación de Lista, como new ArrayList(). Puede pasar la lista original al constructor o bien utilizar el método addAll().

34
List unmodifiableList = Collections.unmodifiableList(list); 

    List newList = new ArrayList(unmodifiableList); 

    Collections.sort(newList); 

El constructor de ArrayList toma una lista existente, se lee en sus elementos (sin modificarlos!), Y los añade a la nueva lista.

0

Debería funcionar como se describe. Los elementos en una Lista no modificable no son modificables por sí mismos. Por supuesto, no puede ordenar una Lista no modificable, porque debe volver a escribirse con operaciones de agregar y eliminar, y no están permitidas.

Supongo que el error está en otro lugar, mejor sería para mostrar su código :)

38

Fwiw, con google-collections que es una sola línea:

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

Parece que anuncia ... Me gusta. – whiskeysierra

+1

¿Solo porque hay una palabra "google"? : p De todos modos. ES UNA PUBLICIDAD. Uno que probablemente no esté pagado. –

0

voy a responder a su segunda pregunta:

No puede agregar a su lista 'taskListModifiable' porque es una lista 'no modificable', que en Java significa que es inmutable. Una lista o colección inmodificable/inmutable de cualquier tipo no se puede modificar directamente de ninguna manera; no puede agregarle elementos, eliminar elementos de ella ni cambiar las referencias a los elementos existentes.

Tenga en cuenta que los elementos existentes en la lista/colección pueden cambiar si son ellos mismos mutables, pero las referencias a ellos de la lista no se pueden cambiar. Es decir, hasta que la lista quede completamente fuera del alcance y se recopile basura, la lista no modificable siempre contendrá esas mismas referencias.

Ahora, en su caso, Collections.emptyList() devuelve una lista vacía inmodificable . En realidad, esta es siempre la misma instancia, ya que es inmutable y está siempre vacía. No puede agregarse debido a la regla de que una lista inmutable no se puede expandir (agregar a). Como está vacío, tampoco hay nada que pueda cambiarse.

Debo aclarar que Collection.emptyList() no crea una lista vacía. Simplemente devuelve una referencia a una instancia de lista singleton.

+2

no modificable * NO ES * inmutable en Java !!Si crea una lista no modificable después de 'list1', y luego agrega/quita objetos a' list1', entonces la lista no modificable reflejará los cambios. –

+0

Eso es cierto para cualquier idioma en el que la colección no modificable simplemente envuelva la otra colección (por ejemplo, no hace una copia segura), no solo Java. Estás hablando de conservar una referencia al objeto envuelto y cambiar eso. Sin embargo, estaba haciendo un comentario (que no pude hacer) a otra respuesta en la que preguntaban por qué no podían cambiar la taskListModifiable específica donde se creó con esto: taskListModifiable = Collections.emptyList(). De hecho, en todos los casos, esto es inmutable porque emptyList() devuelve una lista inmóvil, Singleton, vacía. –

+0

@ True Soft: sí, tienes razón, la lista de respaldo dentro de algunas listas "no modificables" es en realidad modificable. Es cierto que no es estrictamente inmutable y que no necesariamente se puede tratar como tal. Sin embargo, en la práctica, a menudo puede, si crea la lista, hacer que no se pueda modificar, y luego tirar el puntero inicial a la lista. –

4

En Java 8, puede usar la API de secuencias. Por ejemplo:

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