Como posso classificar uma lista em ordem alfabética?


Respostas:


218

Supondo que sejam Strings, use o método estático conveniente sort

 java.util.Collections.sort(listOfCountryNames)

Se você tiver nomes de países como "Reino Unido", isso será quebrado.
Tom Hawtin - tackline 02/04/09

1
Nesse caso, você pode passar um comparador como um argumento extra. Implementar esse comparador seria a parte interessante, no entanto.
Thilo

7
Implemeting o Comparador = utilização java.text.Collator.getInstance
Thilo

143

Solução com Collections.sort

Se você é forçado a usar essa lista ou se seu programa possui uma estrutura como

  • Criar lista
  • Adicione alguns nomes de países
  • classificá-los uma vez
  • nunca mude essa lista novamente

então a resposta de Thilos será a melhor maneira de fazê-lo. Se você combiná-lo com os conselhos de Tom Hawtin - tackline , você obtém:

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

Solução com um TreeSet

Se você é livre para decidir, e se seu aplicativo pode ficar mais complexo, você pode alterar seu código para usar um TreeSet. Esse tipo de coleção classifica suas entradas exatamente quando elas são inseridas. Não há necessidade de chamar sort ().

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

Nota lateral sobre por que prefiro o TreeSet

Isso tem algumas vantagens sutis, mas importantes:

  • É simplesmente mais curto. Apenas uma linha mais curta, no entanto.
  • Nunca se preocupe, esta lista está realmente classificada agora, porque um TreeSet está sempre classificado, não importa o que você faça.
  • Você não pode ter entradas duplicadas. Dependendo da sua situação, isso pode ser um profissional ou um trapaceiro. Se você precisar de duplicatas, atenha-se à sua lista.
  • Um programador experiente examina TreeSet<String> countyNamese sabe instantaneamente: esta é uma coleção ordenada de Strings sem duplicatas, e posso ter certeza de que isso é verdade a todo momento . Tanta informação em uma breve declaração.
  • O desempenho real ganha em alguns casos. Se você usa uma Lista e insere valores com muita frequência, e a lista pode ser lida entre essas inserções, é necessário classificar a lista após cada inserção. O aparelho faz o mesmo, mas muito mais rápido.

Usar a coleção certa para a tarefa certa é a chave para escrever um código curto e sem erros. Não é tão demonstrativo neste caso, porque você salva apenas uma linha. Mas parei de contar com que frequência vejo alguém usando uma Lista quando deseja garantir que não haja duplicatas e, então, constroem essa funcionalidade. Ou pior, usando duas listas quando você realmente precisa de um mapa.

Não me interpretem mal: o uso de Collections.sort não é um erro ou falha. Mas há muitos casos em que o TreeSet é muito mais limpo.


Não vejo nenhuma vantagem em usar o TreeSet sobre a classificação.
DJClayworth

1
O TreeSet evita a duplicação acidental (que pode ser boa ou ruim) e deve ser mais rápida (embora não muito devido ao tamanho da entrada) e sempre será classificada em vez de após todas as entradas (a menos que você classifique a lista após cada inserir) que pode ser importante, mas provavelmente não. Tão rápido ...
TofuBeer 02/04/09

1
@TofuBeer Eu estava apenas esclarecendo isso enquanto você fazia isso também. E se você realmente se preocupam com o que é mais rápido, ter um olhar para stackoverflow.com/questions/168891/...
Lena Schimmel

7
Um TreeSet não permanecerá classificado se os itens forem mutáveis.
21711 Joshua Goldberg

3
@ JoshuaGoldberg Acho que não só será desclassificado, mas também parará de funcionar corretamente. Pelo menos se a mutação do objeto afetar sua ordem de classificação. O conjunto de árvores depende dos itens que estão sendo classificados para executar suas tarefas (como pesquisar, remover, inserir ...).
Lena Schimmel

29

Você pode criar uma nova cópia classificada usando o Java 8 Stream ou o Guava:

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

Outra opção é classificar no local por meio da API de coleções:

Collections.sort(names);

28

Antes tarde do que nunca! Aqui está como podemos fazer isso (apenas para fins de aprendizado) -

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);
        }   
    }
}

4
Novamente, não há justificativa para todo esse código quando uma linha funcionar. Veja a resposta de Lena.
precisa saber é o seguinte

1
isso pode funcionar como um exercício, mas se eu já visse isso no código de produção, eu o macharia. imediatamente.
katzenhut

2
@ james.garriss, a resposta de Lena foi para uma lista simples de strings, isto é para a lista de objetos que contêm atributos de strings a serem classificados.
Muneeb Mirza

Sim, essa resposta é extremamente útil ao trabalhar na produção com objetos. Lista de Strings não é tão comum.
Dominik K


9

Use o argumento dois para de Collections.sort. Você desejará um adequado Comparatorque trate caso apropriado (ou seja, lexical, e não UTF16), como o que pode ser obtido através java.text.Collator.getInstance.


9

A menos que você esteja classificando seqüências de caracteres somente em inglês sem sotaque, você provavelmente desejará usar a Collator. Ele classifica corretamente as marcas diacríticas, pode ignorar maiúsculas e minúsculas e outras coisas específicas do idioma:

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

Você pode definir a força do colador , consulte o javadoc.

Aqui está um exemplo para eslovaco, onde Šdeve ir depois S, mas em UTF Šestá em algum lugar depois 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]

7

Aqui está o que você está procurando

listOfCountryNames.sort(String::compareToIgnoreCase)

1
Não funciona em idiomas com É è etc ... Você precisa retirar o sotaque antes #
Vincent D.

5

Ao usar Collections.sort(), podemos classificar uma 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);
        }
    }
}

resultado:

sudheer
kumar
surendra
kb
[kb, kumar, sudheer, surendra]

4

alfabeto descendente:

List<String> list;
...
Collections.sort(list);
Collections.reverse(list);

Era isso que eu estava procurando. Primeiro, preciso ordenar a lista de volta para AZ e depois ZA para comparação. Boa resposta.
japes Sophey

1

O mesmo no 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));

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;

}
}

Mas por que? Por que é melhor usar essas 50 linhas de código do que a 1 linha de código na resposta de Lena?
James.garriss

Porque, o método sort (Lista <T>, Comparador <? Super T>) é usado para classificar a lista especificada de acordo com a ordem induzida pelo comparador especificado. Quando você quiser classificar uma lista de Emplpyee de acordo com seus nomes e idades, em seguida, usar o método Colecções sort (Lista, comparador)

Não, desculpe, não sentindo nenhum amor aqui. Você está respondendo a uma pergunta diferente, a saber, como classificar uma lista de objetos por suas propriedades. Seu código pode ser útil para esse fim, mas é um exagero para a pergunta do OP. :-(
james.garriss

-12

Você pode tentar usar um método que eu criei.

String key- será a ordem que você deseja e, neste caso, em ordem alfabética. Basta colocar "abc ...".

String list[] - a lista que você deseja colocar em ordem usando a tecla

int index - defina como 0, definirá o deslocamento para a tecla.

    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()]);
}

32
Claro, por que usar java.util.Collections.sort (lista) se eu posso escrever 30 linhas de código :)
jirka

1
Por que tantos votos negativos aqui? alguém já tentou executar esse código ou tentando entender o algoritmo usado?
JBoy
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.