Comment puis-je trier une liste par ordre alphabétique?


Réponses:


225

En supposant que ce sont des chaînes, utilisez la méthode statique pratique sort

 java.util.Collections.sort(listOfCountryNames)

Si vous avez des noms de pays tels que "Royaume-Uni", cela ne fonctionnera pas.
Tom Hawtin - tackline

1
Dans ce cas, vous pouvez passer un comparateur comme argument supplémentaire. La mise en œuvre de ce comparateur serait cependant la partie intéressante.
Thilo

7
Implémentation du comparateur = use java.text.Collator.getInstance
Thilo

145

Solution avec Collections.sort

Si vous êtes obligé d'utiliser cette liste, ou si votre programme a une structure comme

  • Créer une liste
  • Ajouter quelques noms de pays
  • les trier une fois
  • ne changez plus jamais cette liste

alors la réponse de Thilos sera la meilleure façon de le faire. Si vous le combinez avec les conseils de Tom Hawtin - tackline , vous obtenez:

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

Solution avec un TreeSet

Si vous êtes libre de décider et si votre application peut devenir plus complexe, vous pouvez modifier votre code pour utiliser un TreeSet à la place. Ce type de collection trie vos entrées au moment où elles sont insérées. Pas besoin d'appeler sort ().

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

Note latérale sur les raisons pour lesquelles je préfère le TreeSet

Cela présente des avantages subtils mais importants:

  • C'est simplement plus court. Une seule ligne plus courte, cependant.
  • Ne vous inquiétez pas, cette liste est vraiment triée en ce moment car un TreeSet est toujours trié, peu importe ce que vous faites.
  • Vous ne pouvez pas avoir d'entrées en double. Selon votre situation, cela peut être un avantage ou un inconvénient. Si vous avez besoin de doublons, respectez votre liste.
  • Un programmeur expérimenté regarde TreeSet<String> countyNameset sait instantanément: il s'agit d'une collection triée de chaînes sans doublons, et je peux être sûr que cela est vrai à chaque instant . Autant d'informations dans une courte déclaration.
  • La vraie performance gagne dans certains cas. Si vous utilisez une liste et insérez des valeurs très souvent et que la liste peut être lue entre ces insertions, vous devez trier la liste après chaque insertion. L'ensemble fait de même, mais le fait beaucoup plus rapidement.

Utiliser la bonne collection pour la bonne tâche est une clé pour écrire un code court et sans bogue. Ce n'est pas aussi démonstratif dans ce cas, car vous ne sauvegardez qu'une seule ligne. Mais j'ai arrêté de compter le nombre de fois où je vois quelqu'un utiliser une liste quand il veut s'assurer qu'il n'y a pas de doublons, puis construit cette fonctionnalité lui-même. Ou pire encore, utiliser deux listes lorsque vous avez vraiment besoin d'une carte.

Ne vous méprenez pas: l'utilisation de Collections.sort n'est ni une erreur ni un défaut. Mais il existe de nombreux cas où le TreeSet est beaucoup plus propre.


Je ne vois aucun avantage à utiliser TreeSet par rapport au tri.
DJClayworth

1
Eh bien TreeSet évite la duplication accidentelle (qui peut être bonne ou mauvaise) et il devrait être plus rapide (mais pas de beaucoup compte tenu de la taille de l'entrée) et il sera toujours trié plutôt que trié après toutes les entrées (sauf si vous triez la liste après chaque insérer) ce qui peut avoir de l'importance, mais probablement pas. Tellement plus rapide ..
TofuBeer

1
@TofuBeer J'étais juste en train de clarifier cela pendant que vous le faisiez aussi. Et si vous vous souciez vraiment de ce qui est le plus rapide, jetez un œil à stackoverflow.com/questions/168891/…
Lena Schimmel

8
Un TreeSet ne restera pas trié si les éléments sont modifiables.
Joshua Goldberg

3
@JoshuaGoldberg Je pense que non seulement il ne sera pas trié, mais il cessera également de fonctionner correctement. Au moins si la mutation de l'objet affecte son ordre de tri. L'arborescence repose sur les éléments triés pour effectuer ses tâches (comme la recherche, la suppression, l'insertion ...).
Lena Schimmel

30

Vous pouvez créer une nouvelle copie triée à l'aide de Java 8 Stream ou Guava:

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

Une autre option consiste à trier sur place via l'API Collections:

Collections.sort(names);

28

Mieux vaut tard que jamais! Voici comment nous pouvons le faire (à des fins d'apprentissage uniquement) -

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

5
Encore une fois, aucune justification pour tout ce code lorsqu'une seule ligne fera l'affaire. Voir la réponse de Lena.
james.garriss

1
cela pourrait fonctionner comme un exercice, mais si jamais je voyais cela dans le code de production, je le supprimerais. immédiatement.
katzenhut

2
@ james.garriss, la réponse de Lena était pour une simple liste de chaînes, c'est pour une liste d'objets contenant un attribut de chaîne à trier.
Muneeb Mirza

1
Oui, cette réponse est extrêmement utile lorsque vous travaillez en production avec des objets. La liste des chaînes n'est pas si courante.
Dominik K le

16

En une seule ligne, en utilisant Java 8:

list.sort(Comparator.naturalOrder());

11

À moins que vous ne triiez les chaînes dans un anglais sans accent uniquement, vous souhaiterez probablement utiliser un fichier Collator. Il triera correctement les signes diacritiques, peut ignorer la casse et d'autres éléments spécifiques à la langue:

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

Vous pouvez définir la force de l'assemblage, voir le javadoc.

Voici un exemple pour le slovaque où Šdevrait aller après S, mais dans UTF Šest quelque part aprè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]

9

Utilisez les deux arguments pour de Collections.sort. Vous voudrez un convenable Comparatorqui traite la casse appropriée (c'est-à-dire qui fait un ordre lexical, pas UTF16), comme celui qui peut être obtenu via java.text.Collator.getInstance.


7

Voici ce que vous recherchez

listOfCountryNames.sort(String::compareToIgnoreCase)

1
Ne fonctionne pas sur les langues avec É è etc ... Vous devez supprimer les accents avant
Vincent D.

6

En utilisant Collections.sort(), nous pouvons trier une liste.

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

production:

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

4

alphabet décroissant:

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

C'est ce que je cherchais. Tout d'abord, je dois trier la liste en AZ, puis en ZA pour comparaison. Bonne réponse.
japes Sophey

1

Idem dans 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;

}
}

Mais pourquoi? Pourquoi est-il préférable d'utiliser ces 50 lignes de code que la 1 ligne de code dans la réponse de Lena?
james.garriss

Parce que, la méthode sort (List <T>, Comparator <? Super T>) est utilisée pour trier la liste spécifiée selon l'ordre induit par le comparateur spécifié. Lorsque vous souhaitez trier une liste d'employés en fonction de leurs noms et âges, utilisez la méthode de tri des collections (liste, comparateur)

Non, désolé, je ne ressens aucun amour ici. Vous répondez à une autre question, à savoir comment trier une liste d'objets en fonction de leurs propriétés. Votre code peut être utile à cette fin, mais c'est bien exagéré pour la question du PO. :-(
james.garriss

-11

Vous pouvez essayer d'utiliser une méthode que j'ai créée.

String key- sera l'ordre que vous voulez et dans ce cas par ordre alphabétique. Mettez simplement "abc ...".

String list[] - la liste que vous souhaitez mettre en ordre à l'aide de la touche.

int index - mis à 0, définira le décalage de la clé.

    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
Bien sûr, pourquoi utiliser java.util.Collections.sort (list) si je peux écrire 30 lignes de code :)
Jirka

2
Pourquoi tant de votes négatifs ici? quelqu'un a-t-il même essayé d'exécuter ce code ou d'essayer de comprendre l'algorithme utilisé?
JBoy
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.