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 Seto Bagcolecciones en su lugar
NOTA: 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. Implementa SortedSete NavigableSetinteractúa y funciona como probablemente esperarías de una lista:
TreeSet<String> set = new TreeSet<String>();
set.add("lol");
set.add("cat");
// automatically sorts natural order when adding
for (String s : set) {
System.out.println(s);
}
// Prints out "cat" and "lol"
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, Setque permite elementos duplicados, y hay implementaciones de terceros de ellos. Más notablemente de las bibliotecas de guayaba hay un TreeMultiset, que funciona mucho como el TreeSet.
2. Ordene su lista con Collections.sort()
Como se mencionó anteriormente, la clasificación de Lists 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:
List<String> strings = new ArrayList<String>()
strings.add("lol");
strings.add("cat");
Collections.sort(strings);
for (String s : strings) {
System.out.println(s);
}
// Prints out "cat" and "lol"
Usando comparadores
Un beneficio claro es que puede usarlo Comparatoren el sortmétodo. Java también proporciona algunas implementaciones para Comparator, como la Collatorque es útil para cadenas de clasificación sensibles a la configuración regional. Aquí hay un ejemplo:
Collator usCollator = Collator.getInstance(Locale.US);
usCollator.setStrength(Collator.PRIMARY); // ignores casing
Collections.sort(strings, usCollator);
Ordenar en entornos concurrentes
Sin embargo, tenga en cuenta que el uso del sortmé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 la Orderingclase y es simple:
List<string> sorted = Ordering.natural().sortedCopy(strings);
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.PriorityQueueclase.
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 PriorityQueueiterador
La PriorityQueueclase implementa las interfaces Iterable<E>y Collection<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 hacer poll()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 :
List<String> strings = new ArrayList<String>()
strings.add("lol");
strings.add("cat");
PriorityQueue<String> sortedStrings = new PriorityQueue(strings);
while(!sortedStrings.isEmpty()) {
System.out.println(sortedStrings.poll());
}
// Prints out "cat" and "lol"
4. Escribe tu propia SortedListclase
NOTA: 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:
- Rompe el contrato que
List<E>tiene la interfaz porque los addmétodos deben garantizar que el elemento residirá en el índice que el usuario especifique.
- ¿Por qué reinventar la rueda? En su lugar, debe usar TreeSet o Multisets como se señala en el primer punto anterior.
Sin embargo, si desea hacerlo como ejercicio, aquí hay una muestra de código para comenzar, utiliza la AbstractListclase abstracta:
public class SortedList<E> extends AbstractList<E> {
private ArrayList<E> internalList = new ArrayList<E>();
// Note that add(E e) in AbstractList is calling this one
@Override
public void add(int position, E e) {
internalList.add(e);
Collections.sort(internalList, null);
}
@Override
public E get(int i) {
return internalList.get(i);
}
@Override
public int size() {
return internalList.size();
}
}
Tenga en cuenta que si no ha anulado los métodos que necesita, las implementaciones predeterminadas de AbstractListarrojarán UnsupportedOperationExceptions.