¿Cómo puedo ordenar una lista alfabéticamente?

Respuestas:

218

Suponiendo que se trata de cadenas, utilice el método estático conveniente sort...

 java.util.Collections.sort(listOfCountryNames)
Thilo
fuente
Si tiene nombres de países como "Reino Unido", eso se romperá.
Tom Hawtin - tackline el
1
En este caso, puede pasar un Comparador como argumento adicional. Sin embargo, implementar ese Comparador sería la parte interesante.
Thilo
77
Implementación del comparador = use java.text.Collator.getInstance
Thilo
143

Solución con Collections.sort

Si se ve obligado a usar esa Lista, o si su programa tiene una estructura como

  • Crear lista
  • Agrega algunos nombres de países
  • ordenarlos una vez
  • nunca cambie esa lista de nuevo

entonces la respuesta de Thilos será la mejor manera de hacerlo. Si lo combina con el consejo de Tom Hawtin - tackline , obtendrá:

java.util.Collections.sort(listOfCountryNames, Collator.getInstance());

Solución con un TreeSet

Si es libre de decidir, y si su aplicación puede volverse más compleja, puede cambiar su código para usar un TreeSet. Este tipo de colección clasifica sus entradas justo cuando se insertan. No es necesario llamar a sort ().

Collection<String> countryNames = 
    new TreeSet<String>(Collator.getInstance());
countryNames.add("UK");
countryNames.add("Germany");
countryNames.add("Australia");
// Tada... sorted.

Nota al margen sobre por qué prefiero el TreeSet

Esto tiene algunas ventajas sutiles, pero importantes:

  • Es simplemente más corto. Sin embargo, solo una línea más corta.
  • No se preocupe, esta lista está realmente ordenada en este momento porque un TreeSet siempre está ordenado, sin importar lo que haga.
  • No puede tener entradas duplicadas. Dependiendo de su situación, esto puede ser un profesional o una estafa. Si necesita duplicados, manténgase en su Lista.
  • Un programador experimentado observa TreeSet<String> countyNamesy sabe al instante: esta es una colección ordenada de cadenas sin duplicados, y puedo estar seguro de que esto es cierto en todo momento . Tanta información en una breve declaración.
  • Rendimiento real ganar en algunos casos. Si usa una Lista e inserta valores muy a menudo, y la lista puede leerse entre esas inserciones, entonces debe ordenar la lista después de cada inserción. El conjunto hace lo mismo, pero lo hace mucho más rápido.

Usar la colección correcta para la tarea correcta es una clave para escribir código corto y libre de errores. No es tan demostrativo en este caso, porque solo guarda una línea. Pero he dejado de contar la frecuencia con la que veo a alguien usando una Lista cuando quieren asegurarse de que no haya duplicados, y luego construir esa funcionalidad ellos mismos. O peor aún, usando dos listas cuando realmente necesita un mapa.

No me malinterpreten: el uso de Collections.sort no es un error o una falla. Pero hay muchos casos en que TreeSet es mucho más limpio.

Lena Schimmel
fuente
No veo ninguna ventaja al usar TreeSet sobre la clasificación.
DJClayworth el
1
Bueno, TreeSet evita la duplicación accidental (que puede ser buena o mala) y debería ser más rápido (aunque no mucho dado el tamaño de la entrada) y siempre se ordenará en lugar de ordenar después de toda la entrada (a menos que ordene la lista después de cada insert) que puede importar, pero probablemente no. Tan rápido ..
TofuBeer 02 de
1
@TofuBeer Estaba aclarando esto mientras lo hacías tú también. Y si realmente le importa lo que es más rápido, eche un vistazo a stackoverflow.com/questions/168891/…
Lena Schimmel el
77
Un TreeSet no se mantendrá ordenado si los elementos son mutables.
Joshua Goldberg
3
@ JoshuaGoldberg Creo que no solo se desordenará, sino que también dejará de funcionar correctamente. Al menos si la mutación del objeto afecta su orden de clasificación. El conjunto de árbol se basa en los elementos que se ordenan para realizar sus tareas (como buscar, eliminar, insertar ...).
Lena Schimmel
29

Puede crear una nueva copia ordenada usando Java 8 Stream o Guava:

// Java 8 version
List<String> sortedNames = names.stream().sorted().collect(Collectors.toList());
// Guava version
List<String> sortedNames = Ordering.natural().sortedCopy(names); 

Otra opción es ordenar en el lugar a través de la API de colecciones:

Collections.sort(names);
Vitalii Fedorenko
fuente
28

¡Mejor tarde que nunca! Así es como podemos hacerlo (solo con fines de aprendizaje):

import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

class SoftDrink {
    String name;
    String color;
    int volume; 

    SoftDrink (String name, String color, int volume) {
        this.name = name;
        this.color = color;
        this.volume = volume;
    }
}

public class ListItemComparision {
    public static void main (String...arg) {
        List<SoftDrink> softDrinkList = new ArrayList<SoftDrink>() ;
        softDrinkList .add(new SoftDrink("Faygo", "ColorOne", 4));
        softDrinkList .add(new SoftDrink("Fanta",  "ColorTwo", 3));
        softDrinkList .add(new SoftDrink("Frooti", "ColorThree", 2));       
        softDrinkList .add(new SoftDrink("Freshie", "ColorFour", 1));

        Collections.sort(softDrinkList, new Comparator() {
            @Override
            public int compare(Object softDrinkOne, Object softDrinkTwo) {
                //use instanceof to verify the references are indeed of the type in question
                return ((SoftDrink)softDrinkOne).name
                        .compareTo(((SoftDrink)softDrinkTwo).name);
            }
        }); 
        for (SoftDrink sd : softDrinkList) {
            System.out.println(sd.name + " - " + sd.color + " - " + sd.volume);
        }
        Collections.sort(softDrinkList, new Comparator() {
            @Override
            public int compare(Object softDrinkOne, Object softDrinkTwo) {
                //comparision for primitive int uses compareTo of the wrapper Integer
                return(new Integer(((SoftDrink)softDrinkOne).volume))
                        .compareTo(((SoftDrink)softDrinkTwo).volume);
            }
        });

        for (SoftDrink sd : softDrinkList) {
            System.out.println(sd.volume + " - " + sd.color + " - " + sd.name);
        }   
    }
}
Tirath
fuente
44
Nuevamente, no hay justificación para todo este código cuando una línea lo hará. Ver la respuesta de Lena.
james.garriss
1
Esto podría funcionar como un ejercicio, pero si alguna vez lo viera en el código de producción, lo eliminaría. inmediatamente.
katzenhut
2
@ james.garriss, la respuesta de Lena fue para una simple lista de cadenas, esto es para la lista de objetos que contiene el atributo de cadena que se debe ordenar.
Muneeb Mirza
Sí, esta respuesta es extremadamente útil cuando se trabaja en producción con objetos. La lista de cadenas no es tan común.
Dominik K
14

En una línea, usando Java 8:

list.sort(Comparator.naturalOrder());
Victor Petit
fuente
9

Utilice los dos argumentos para de Collections.sort. ComparatorQuerrá un adecuado que trate el caso apropiado (es decir, hace un pedido léxico, no UTF16), como el que se puede obtener a través de java.text.Collator.getInstance.

Tom Hawtin - tackline
fuente
9

A menos que esté clasificando cadenas solo en inglés sin acento, probablemente quiera usar a Collator. Clasificará correctamente los signos diacríticos, puede ignorar mayúsculas y minúsculas y otras cosas específicas del idioma:

Collections.sort(countries, Collator.getInstance(new Locale(languageCode)));

Puede establecer la fuerza del intercalador , ver el javadoc.

Aquí hay un ejemplo para el eslovaco donde Šdebería ir después S, pero en UTF Šestá en algún lugar después Z:

List<String> countries = Arrays.asList("Slovensko", "Švédsko", "Turecko");

Collections.sort(countries);
System.out.println(countries); // outputs [Slovensko, Turecko, Švédsko]

Collections.sort(countries, Collator.getInstance(new Locale("sk")));
System.out.println(countries); // outputs [Slovensko, Švédsko, Turecko]
Oliv
fuente
7

Esto es lo que buscas

listOfCountryNames.sort(String::compareToIgnoreCase)
prashant
fuente
1
No funciona en idiomas con É è, etc ... Es necesario eliminar los acentos antes
Vincent D.
5

Al usar Collections.sort(), podemos ordenar una lista.

public class EmployeeList {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        List<String> empNames= new ArrayList<String>();

        empNames.add("sudheer");
        empNames.add("kumar");
        empNames.add("surendra");
        empNames.add("kb");

        if(!empNames.isEmpty()){

            for(String emp:empNames){

                System.out.println(emp);
            }

            Collections.sort(empNames);

            System.out.println(empNames);
        }
    }
}

salida:

sudheer
kumar
surendra
kb
[kb, kumar, sudheer, surendra]
ASR
fuente
4

alfabeto descendente:

List<String> list;
...
Collections.sort(list);
Collections.reverse(list);
norbDEV
fuente
Esto es lo que estaba buscando. Primero necesito ordenar la lista de nuevo a AZ, y luego ZA para comparar. Buena respuesta.
Japes Sophey
1

Lo mismo en JAVA 8: -

//Assecnding order
        listOfCountryNames.stream().sorted().forEach((x) -> System.out.println(x));

//Decending order
        listOfCountryNames.stream().sorted((o1, o2) -> o2.compareTo(o1)).forEach((x) -> System.out.println(x));
Opster Elasticsearch Pro-Vijay
fuente
0
//Here is sorted List alphabetically with syncronized
package com.mnas.technology.automation.utility;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;
/**
* 
* @author manoj.kumar
*/
public class SynchronizedArrayList {
static Logger log = Logger.getLogger(SynchronizedArrayList.class.getName());
@SuppressWarnings("unchecked")
public static void main(String[] args) {

List<Employee> synchronizedList = Collections.synchronizedList(new ArrayList<Employee>());
synchronizedList.add(new Employee("Aditya"));
synchronizedList.add(new Employee("Siddharth"));
synchronizedList.add(new Employee("Manoj"));
Collections.sort(synchronizedList, new Comparator() {
public int compare(Object synchronizedListOne, Object synchronizedListTwo) {
//use instanceof to verify the references are indeed of the type in question
return ((Employee)synchronizedListOne).name
.compareTo(((Employee)synchronizedListTwo).name);
}
}); 
/*for( Employee sd : synchronizedList) {
log.info("Sorted Synchronized Array List..."+sd.name);
}*/

// when iterating over a synchronized list, we need to synchronize access to the synchronized list
synchronized (synchronizedList) {
Iterator<Employee> iterator = synchronizedList.iterator();
while (iterator.hasNext()) {
log.info("Sorted Synchronized Array List Items: " + iterator.next().name);
}
}

}
}
class Employee {
String name;
Employee (String name) {
this.name = name;

}
}

fuente
¿Pero por qué? ¿Por qué es mejor usar estas 50 líneas de código que la 1 línea de código en la respuesta de Lena?
james.garriss
Porque, el método sort (List <T>, Comparator <? Super T>) se usa para ordenar la lista especificada de acuerdo con el orden inducido por el comparador especificado. Cuando desee ordenar una lista de Emplpyee de acuerdo con sus nombres y edades, utilice el método
No, lo siento, no siento ningún amor aquí. Está respondiendo una pregunta diferente, a saber, cómo ordenar una Lista de objetos por sus propiedades. Su código puede ser útil para ese propósito, pero es demasiado exagerado para la pregunta del OP. :-(
james.garriss
-12

Puedes intentar usar un método que hice.

String key- será el orden que desee y en este caso en orden alfabético. Solo pon "abc ...".

String list[] - la lista que desea ordenar con la tecla.

int index - Establecer como 0, establecerá el desplazamiento de la clave.

    public static String[] order(String key, String list[], int index) {
    ArrayList<String> order_List = new ArrayList<String>();
    ArrayList<String> temp_Order_List = null;
    char[] key_char = key.toCharArray();
    for (int offset = 0; offset < key_char.length; offset++) {
        if (key_char.length >= offset + index) {
            String str = (index > 1 ? list[0].substring(0, index - 1) : "")
                    + new String(key_char, offset, 1);
            for (int i = 0; i < list.length; i++) {
                temp_Order_List = new ArrayList<String>();
                for (int k = 0; k < list.length; k++) {
                    if (!order_List.contains(list[k])
                            && !temp_Order_List.contains(list[k])) {
                        if (list[k].equalsIgnoreCase(str))
                            order_List.add(list[k]);
                        else if (list[k].toLowerCase().startsWith(str.toLowerCase())) {
                            temp_Order_List.add(list[k]);

                        }
                    }
                }
                if (temp_Order_List.size() > 0) {
                    if (temp_Order_List.size() > 1) {
                        String[] add = order(key,
                                temp_Order_List.toArray(new String[temp_Order_List
                                        .size()]), index + 1);
                        for (String s : add) {
                            order_List.add(s);
                        }
                    } else {
                        order_List.add(temp_Order_List.get(0));
                    }
                }
            }
        }
    }
    return order_List.toArray(new String[order_List.size()]);
}
Hacer fuera
fuente
32
Claro, ¿por qué usar java.util.Collections.sort (list) si puedo escribir 30 líneas de código :)
Jirka
1
¿Por qué tantos votos negativos aquí? ¿Alguien ha intentado ejecutar este código o tratando de entender el algoritmo utilizado?
JBoy