Comment trier un ensemble dans une liste en Java?

169

En Java, j'ai un Set, et je veux le transformer en un fichier trié List. Y a-t-il une méthode dans le java.util.Collectionspackage qui fera cela pour moi?

Jeremy Stein
la source

Réponses:

214

La réponse fournie par le PO n'est pas la meilleure. Il est inefficace, car il crée un nouveau tableau List et un nouveau tableau inutile. En outre, il déclenche des avertissements «non contrôlés» en raison des problèmes de sécurité de type autour des tableaux génériques.

À la place, utilisez quelque chose comme ceci:

public static
<T extends Comparable<? super T>> List<T> asSortedList(Collection<T> c) {
  List<T> list = new ArrayList<T>(c);
  java.util.Collections.sort(list);
  return list;
}

Voici un exemple d'utilisation:

Map<Integer, String> map = new HashMap<Integer, String>();
/* Add entries to the map. */
...
/* Now get a sorted list of the *values* in the map. */
Collection<String> unsorted = map.values();
List<String> sorted = Util.asSortedList(unsorted);
Erickson
la source
3
Merci! Ce SuppressWarnings m'a toujours dérangé.
Jeremy Stein
4
@sunleo La Utilclasse est celle qui contient la asSortedList()méthode que j'ai écrite. En d'autres termes, vous écrivez la Utilclasse vous-même et y mettez ce code.
erickson
1
ha ha je pensais que c'était du pack par défaut comme java.util ok merci.
sunleo
3
Cela pourrait être une fonction utilitaire générique intéressante, mais le fait est qu'elle n'est toujours pas efficace. Envisagez le tri sur place en vous assurant que votre ensemble est dans le bon conteneur pour commencer. Pensez également à utiliser le TreeSet comme conteneur direct de vos données. Si vos données doivent être uniques de toute façon et que vous avez besoin d'un ensemble, utilisez le TreeSet, attrape deux mouches en un seul coup.
YoYo
1
En guise de note aux personnes qui ne lisent que la réponse principale: Jetez un œil à la réponse de nschum ci-dessous, qui utilise les flux de Java 8. Si vous pouvez utiliser Java 8, allez-y. ils sont plus flexibles et efficaces.
Felk
74

Ensemble trié:

return new TreeSet(setIWantSorted);

ou:

return new ArrayList(new TreeSet(setIWantSorted));
Steve B.
la source
C'était ma première pensée, mais le demandeur voulait une liste
Alex B
@Alex: Cette approche peut toujours être utilisée; return new ArrayList (new TreeSet (setIWantSorted))
Jonik
1
J'ai en fait utilisé cette solution, mais je ne le conseillerais pas. Comme l'indique la documentation sur TreeSet (voir download.oracle.com/javase/1.4.2/docs/api/java/util/… ), il utilise effectivement la méthode compareTo () au lieu de la méthode equals () - donc si vous ont deux objets dans l'ensemble qui ont le même résultat equals (), ils seront considérés comme des doublons et, en tant que tels, ne seront pas ajoutés au TreeSet. Il faut se méfier.
fwielstra
24
@fwielstra: Comment pouvez-vous avoir des objets égaux dans l'entrée puisque l'entrée est également un Set?
ryanprayogo
2
@ryanprayogo Cela vaut la peine de mentionner, comme l' new TreeSetaccepte Collections, pas seulement Sets. Tous ceux qui liront cette réponse n'utiliseront pas un Set, même si c'est ce que la question initiale pose.
Chris
44
List myList = new ArrayList(collection);
Collections.sort(myList);

… Devrait faire l'affaire cependant. Ajoutez de la saveur avec des génériques, le cas échéant.

Esko
la source
J'avais un extrait utile que je voulais donner à la communauté. Lorsque j'ai recherché les informations, je ne les ai pas trouvées. J'essayais de faciliter le travail de la personne suivante. stackoverflow.com/questions/18557/…
Jeremy Stein
1
Oui, bien sûr, mais ce lien que vous avez fourni parle en fait de vraies questions (c'est-à-dire celles pour lesquelles n'ont pas de réponse, alors trouvez-la). Votre question ici était seulement de donner la réponse ... Je pourrais en fait entrer des centaines de questions et répondre moi-même; ce n'est pas le propos!
Seb
5
@Seb: Je ne suis pas d'accord. Je ne vois rien de mal à cette question. Ce n'était évidemment pas une question extrêmement simple, et maintenant il connaît un meilleur moyen qu'avant!
Michael Myers
3
Il était une vraie question, mais je l' ai trouvé la réponse moi - même après que Google est venu court. Stackoverflow n'existait pas à l'époque. Je l'ai fait publier sur mon site Web et cela a aidé quelqu'un d'autre, alors j'ai pensé que cela pourrait être utile ici.
Jeremy Stein
Bonus: Et si vous triez votre propre type d'objet, vous pouvez toujours implémenter Comparableet remplacer la compareTométhode.
nabster le
42

Voici comment vous pouvez le faire avec les flux de Java 8:

mySet.stream().sorted().collect(Collectors.toList());

ou avec un comparateur personnalisé:

mySet.stream().sorted(myComparator).collect(Collectors.toList());
nschum
la source
9

Utilisez toujours en toute sécurité l'interface Comparator ou Comparable pour fournir une implémentation de tri (si l'objet n'est pas une classe String ou Wrapper pour les types de données primitifs). Comme exemple d'implémentation d'un comparateur pour trier les employés en fonction du nom

    List<Employees> empList = new LinkedList<Employees>(EmpSet);

    class EmployeeComparator implements Comparator<Employee> {

            public int compare(Employee e1, Employee e2) {
                return e1.getName().compareTo(e2.getName());
            }

        }

   Collections.sort(empList , new EmployeeComparator ());

Le comparateur est utile lorsque vous avez besoin d'un algorithme de tri différent sur le même objet (Dites le nom de l'emp, le salaire de l'emp, etc.). Le tri en mode unique peut être implémenté à l'aide de l'interface Comparable dans l'objet requis.

Satheesh Cheveri
la source
5

Il n'y a pas de méthode unique pour faire cela. Utilisez ceci:

@SuppressWarnings("unchecked")
public static <T extends Comparable> List<T> asSortedList(Collection<T> collection) {
  T[] array = collection.toArray(
    (T[])new Comparable[collection.size()]);
  Arrays.sort(array);
  return Arrays.asList(array);
}
Jeremy Stein
la source
Il existe également une fonction Collections.sort, mais je pense qu'elle fait la même chose. +1 de toute façon.
CookieOfFortune
1
Collections.sort prend une liste comme paramètre.
Jeremy Stein
3

Vous pouvez convertir un ensemble en un ArrayList, où vous pouvez trier l' ArrayListutilisation Collections.sort(List).

Voici le code:

keySet = (Set) map.keySet();
ArrayList list = new ArrayList(keySet);     
Collections.sort(list);
Amit
la source
3
TreeSet sortedset = new TreeSet();
sortedset.addAll(originalset);

list.addAll(sortedset);

où originalset = ensemble non trié et liste = la liste à renvoyer

Sujith Mohan
la source
TreeSet dédupe également la liste, ce qui peut entraîner un résultat erroné si vous ne le supposez pas.
anthonymonori le
2

@Jeremy Stein Je voulais implémenter le même code. De plus, je voulais trier l'ensemble en liste, donc au lieu d'utiliser Set, j'ai converti les valeurs d'ensemble en liste et trier cette liste en fonction de sa variable. Ce code m'a aidé,

set.stream().sorted(Comparator.comparing(ModelClassName::sortingVariableName)).collect(Collectors.toList());
Deepak Kumbhar
la source
0

J'utilise ce code, que je trouve plus pratique que la réponse acceptée ci-dessus:

List<Thing> thingList = new ArrayList<>(thingSet);
thingList.sort((thing1, thing2) -> thing1.getName().compareToIgnoreCase(thing2.getName()));
nn4l
la source