En Java existen las interfaces SortedSet
y SortedMap
. Ambos pertenecen al marco de Java Collections y proporcionan una forma ordenada de acceder a los elementos.
Sin embargo, según tengo entendido, no hay SortedList
en Java. Puede usar java.util.Collections.sort()
para ordenar una lista.
¿Alguna idea de por qué está diseñado así?
java
sorting
collections
Jijoy
fuente
fuente
int diff = this.score - that.score;
return (diff == 0) ? 1 : diff;
como es un truco maloliente, proporcionaría esto como un argumento de constructor anónimo en lugar de tener ningún implemento Comparable.Respuestas:
Los iteradores de lista garantizan en primer lugar que obtiene los elementos de la lista en el orden interno de la lista (también conocido como orden de inserción ). Más específicamente, está en el orden en que ha insertado los elementos o en cómo ha manipulado la lista. La ordenación puede verse como una manipulación de la estructura de datos, y hay varias formas de ordenar la lista.
Ordenaré las formas en el orden de utilidad tal como lo veo personalmente:
1. Considere usar
Set
oBag
colecciones en su lugarNOTA: pongo esta opción en la parte superior porque esto es lo que normalmente quieres hacer de todos modos.
Un conjunto ordenado clasifica automáticamente la colección en la inserción , lo que significa que realiza la clasificación mientras agrega elementos a la colección. También significa que no necesita ordenarlo manualmente.
Además, si está seguro de que no necesita preocuparse por (o tener) elementos duplicados, puede usar el
TreeSet<T>
en su lugar. ImplementaSortedSet
eNavigableSet
interactúa y funciona como probablemente esperarías de una lista:Si no desea el orden natural, puede usar el parámetro constructor que toma a
Comparator<T>
.Alternativamente, puede usar Multisets (también conocidos como Bolsas ) , es decir,
Set
que permite elementos duplicados, y hay implementaciones de terceros de ellos. Más notablemente de las bibliotecas de guayaba hay unTreeMultiset
, que funciona mucho como elTreeSet
.2. Ordene su lista con
Collections.sort()
Como se mencionó anteriormente, la clasificación de
List
s es una manipulación de la estructura de datos. Entonces, para situaciones en las que necesita "una fuente de verdad" que se clasificará de varias maneras, entonces ordenarlas manualmente es el camino a seguir.Puedes ordenar tu lista con el
java.util.Collections.sort()
método. Aquí hay un ejemplo de código sobre cómo:Usando comparadores
Un beneficio claro es que puede usarlo
Comparator
en elsort
método. Java también proporciona algunas implementaciones paraComparator
, como laCollator
que es útil para cadenas de clasificación sensibles a la configuración regional. Aquí hay un ejemplo:Ordenar en entornos concurrentes
Sin embargo, tenga en cuenta que el uso del
sort
método no es amigable en entornos concurrentes, ya que la instancia de la colección será manipulada, y debería considerar el uso de colecciones inmutables. Esto es algo que Guava ofrece en laOrdering
clase y es simple:3. Envuelva su lista con
java.util.PriorityQueue
Aunque no hay una lista ordenada en Java, hay una cola ordenada que probablemente funcione igual de bien para usted. Es la
java.util.PriorityQueue
clase.Nico Haase enlazó en los comentarios a una pregunta relacionada que también responde a esto.
En una colección ordenada, lo más probable es que no desee manipular la estructura de datos interna, por lo que PriorityQueue no implementa la interfaz Lista (porque eso le daría acceso directo a sus elementos).
Advertencia sobre el
PriorityQueue
iteradorLa
PriorityQueue
clase implementa las interfacesIterable<E>
yCollection<E>
para que pueda iterarse como de costumbre. Sin embargo, no se garantiza que el iterador devuelva elementos en el orden ordenado. En cambio (como señala Alderath en los comentarios) necesita hacerpoll()
cola hasta que esté vacío.Tenga en cuenta que puede convertir una lista en una cola prioritaria a través del constructor que toma cualquier colección :
4. Escribe tu propia
SortedList
claseNOTA: No debería tener que hacer esto.
Puede escribir su propia clase Lista que se ordena cada vez que agrega un nuevo elemento. Esto puede hacer que el cálculo sea bastante pesado dependiendo de su implementación y no tiene sentido , a menos que desee hacerlo como un ejercicio, debido a dos razones principales:
List<E>
tiene la interfaz porque losadd
métodos deben garantizar que el elemento residirá en el índice que el usuario especifique.Sin embargo, si desea hacerlo como ejercicio, aquí hay una muestra de código para comenzar, utiliza la
AbstractList
clase abstracta:Tenga en cuenta que si no ha anulado los métodos que necesita, las implementaciones predeterminadas de
AbstractList
arrojaránUnsupportedOperationException
s.fuente
Integer maxVal = prioQueue.peek(prioQueue.size() - 1);
. En segundo lugar, si tiene la intención de utilizar PriorityQueue simplemente como una lista ordenada, sonará menos intuitivo verPriorityQueue
en el código de lo que hubiera sido verSortedList
, si existiera dicha estructura de datos.Collections.sort()
incluso le permite definir la función de comparación que se utiliza para ordenar, mediante el uso de unComparator
objeto.Porque el concepto de una Lista es incompatible con el concepto de una colección ordenada automáticamente. El punto de una Lista es que después de llamar
list.add(7, elem)
,list.get(7)
volverá una llamada aelem
. Con una lista ordenada automáticamente, el elemento podría terminar en una posición arbitraria.fuente
Como todas las listas ya están "ordenadas" por el orden en que se agregaron los elementos (orden FIFO), puede "recurrirlas" con otro orden, incluido el orden natural de los elementos
java.util.Collections.sort()
.EDITAR:
Las listas ya que las estructuras de datos se basan en lo interesante es el orden en que se insertaron los elementos.
Los conjuntos no tienen esa información.
Si desea ordenar agregando tiempo, use
List
. Si desea ordenar por otros criterios, useSortedSet
.fuente
Set y Map son estructuras de datos no lineales. La lista es una estructura de datos lineal.
La estructura de datos de árbol
SortedSet
y lasSortedMap
interfaces implementanTreeSet
yTreeMap
utilizan respectivamente el algoritmo de implementación de árbol rojo-negro utilizado . Por lo tanto, asegúrese de que no haya elementos duplicados (o claves en caso deMap
).List
ya mantiene una colección ordenada y una estructura de datos basada en índices, los árboles no son estructuras de datos basadas en índices.Tree
por definición no puede contener duplicados.List
podemos tener duplicados, por lo que no hayTreeList
(es decir, noSortedList
).java.util.Collections.sort()
. Ordena la lista especificada en orden ascendente, de acuerdo con el orden natural de sus elementos.fuente
JavaFX
SortedList
Aunque tomó un tiempo, Java 8 tiene un orden
List
. http://docs.oracle.com/javase/8/javafx/api/javafx/collections/transformation/SortedList.htmlComo puede ver en los javadocs, forma parte de las colecciones JavaFX , destinadas a proporcionar una vista ordenada en un ObservableList.
Actualización: Tenga en cuenta que con Java 11, el kit de herramientas JavaFX se ha movido fuera del JDK y ahora es una biblioteca separada. JavaFX 11 está disponible como un SDK descargable o desde MavenCentral. Ver https://openjfx.io
fuente
Para cualquier recién llegado, a partir de abril de 2015, Android ahora tiene una clase SortedList en la biblioteca de soporte, diseñada específicamente para trabajar
RecyclerView
. Aquí está la publicación del blog al respecto.fuente
Otro punto es la complejidad temporal de las operaciones de inserción. Para una inserción de lista, se espera una complejidad de O (1). Pero esto no se puede garantizar con una lista ordenada.
Y el punto más importante es que las listas no asumen nada sobre sus elementos. Por ejemplo, puede hacer listas de cosas que no implementan
equals
ocompare
.fuente
SortedSet
de las cosas que no se implementanComparable
. Vea este constructor de TreeSet .List
interfaz Java no garantiza ninguna especificación de rendimiento en sus métodos.Piense en ello como esto: la
List
interfaz tiene métodos comoadd(int index, E element)
,set(int index, E element)
. El contrato es que una vez que haya agregado un elemento en la posición X, lo encontrará allí a menos que agregue o elimine elementos antes.Si cualquier implementación de la lista almacenara elementos en un orden distinto al basado en el índice, los métodos de lista anteriores no tendrían sentido.
fuente
La primera línea de la API de lista dice que es una colección ordenada (también conocida como secuencia). Si ordena la lista, no puede mantener el orden, por lo que no hay TreeList en Java.
Como dice API, Java List se inspiró en Sequence y vea las propiedades de secuencia http://en.wikipedia.org/wiki/Sequence_(mathematics )
No significa que no pueda ordenar la lista, pero Java es estricto con su definición y no proporciona versiones ordenadas de listas de forma predeterminada.
fuente
En caso de que esté buscando una forma de ordenar elementos, pero también poder acceder a ellos por índice de manera eficiente, puede hacer lo siguiente:
ArrayList
. Ej. )Luego, para agregar o eliminar un elemento que puede usar
Collections.binarySearch
para obtener el índice de inserción / eliminación. Como su lista implementa acceso aleatorio, puede modificar eficientemente la lista con el índice determinado.Ejemplo:
fuente
Considere usar indexed-tree-map . Es un TreeSet de JDK mejorado que proporciona acceso al elemento por índice y encuentra el índice de un elemento sin iteración o listas subyacentes ocultas que respaldan el árbol. El algoritmo se basa en actualizar los pesos de los nodos cambiantes cada vez que hay un cambio.
fuente