En Java, il y a les interfaces SortedSet
et SortedMap
. Les deux appartiennent au framework Java Collections et fournissent un moyen trié d'accéder aux éléments.
Cependant, à ma connaissance, il n'y SortedList
en a pas en Java. Vous pouvez utiliser java.util.Collections.sort()
pour trier une liste.
Une idée pourquoi il est conçu comme ça?
java
sorting
collections
Jijoy
la source
la source
int diff = this.score - that.score;
return (diff == 0) ? 1 : diff;
car il s'agit d'un hack malodorant, je fournirais cela comme argument constructeur anonyme plutôt que d'avoir n'importe quel implémenter Comparable.Réponses:
Les itérateurs de liste garantissent avant tout que vous obtenez les éléments de la liste dans l'ordre interne de la liste (aka. Ordre d'insertion ). Plus précisément, c'est dans l'ordre dans lequel vous avez inséré les éléments ou dans la façon dont vous avez manipulé la liste. Le tri peut être considéré comme une manipulation de la structure des données, et il existe plusieurs façons de trier la liste.
Je vais ordonner les chemins dans l'ordre d' utilité tel que je le vois personnellement:
1. Pensez à utiliser
Set
ouBag
collections à la placeREMARQUE: je mets cette option en haut parce que c'est ce que vous voulez normalement faire de toute façon.
Un ensemble trié trie automatiquement la collection à l'insertion , ce qui signifie qu'il effectue le tri pendant que vous ajoutez des éléments dans la collection. Cela signifie également que vous n'avez pas besoin de le trier manuellement.
De plus, si vous êtes sûr de ne pas avoir à vous soucier (ou d'avoir) des éléments en double, vous pouvez utiliser le à la
TreeSet<T>
place. Il implémenteSortedSet
etNavigableSet
interface et fonctionne comme vous l'attendriez probablement d'une liste:Si vous ne voulez pas l'ordre naturel, vous pouvez utiliser le paramètre constructeur qui prend a
Comparator<T>
.Alternativement, vous pouvez utiliser des multisets (également appelés sacs ) , c'est-à-dire
Set
qui autorisent les éléments en double, et il existe des implémentations tierces. Plus particulièrement à partir des bibliothèques de Guava, il y en a unTreeMultiset
, qui fonctionne beaucoup comme leTreeSet
.2. Triez votre liste avec
Collections.sort()
Comme mentionné ci-dessus, le tri de
List
s est une manipulation de la structure des données. Donc, pour les situations où vous avez besoin d'une "source de vérité" qui sera triée de différentes manières, puis la trier manuellement est la voie à suivre.Vous pouvez trier votre liste avec la
java.util.Collections.sort()
méthode. Voici un exemple de code expliquant comment:Utiliser des comparateurs
Un avantage évident est que vous pouvez l'utiliser
Comparator
dans lasort
méthode. Java fournit également quelques implémentations pour leComparator
tel que leCollator
qui est utile pour les chaînes de tri sensibles aux paramètres régionaux. Voici un exemple:Tri dans des environnements simultanés
Notez cependant que l'utilisation de la
sort
méthode n'est pas conviviale dans les environnements simultanés, car l'instance de collection sera manipulée, et vous devriez plutôt envisager d'utiliser des collections immuables. C'est quelque chose que Guava fournit dans laOrdering
classe et c'est un simple doublure:3. Enveloppez votre liste avec
java.util.PriorityQueue
Bien qu'il n'y ait pas de liste triée en Java, il existe cependant une file d'attente triée qui fonctionnerait probablement aussi bien pour vous. C'est la
java.util.PriorityQueue
classe.Nico Haase a lié dans les commentaires une question connexe qui répond également à cela.
Dans une collection triée, vous ne voulez probablement pas manipuler la structure de données interne, c'est pourquoi PriorityQueue n'implémente pas l'interface List (car cela vous donnerait un accès direct à ses éléments).
Avertissement sur l'
PriorityQueue
itérateurLa
PriorityQueue
classe implémente les interfacesIterable<E>
etCollection<E>
afin qu'elle puisse être itérée comme d'habitude. Cependant, l'itérateur n'est pas garanti de renvoyer les éléments dans l'ordre trié. Au lieu de cela (comme le souligne Alderath dans les commentaires), vous devez mettrepoll()
la file d'attente jusqu'à ce qu'elle soit vide.Notez que vous pouvez convertir une liste en file d'attente prioritaire via le constructeur qui prend n'importe quelle collection :
4. Écrivez votre propre
SortedList
classeREMARQUE: vous ne devriez pas avoir à le faire.
Vous pouvez écrire votre propre classe List qui trie chaque fois que vous ajoutez un nouvel élément. Cela peut être assez lourd à calculer en fonction de votre implémentation et est inutile , sauf si vous voulez le faire comme un exercice, pour deux raisons principales:
List<E>
interface car lesadd
méthodes doivent garantir que l'élément résidera dans l'index spécifié par l'utilisateur.Cependant, si vous voulez le faire comme un exercice, voici un exemple de code pour vous aider à démarrer, il utilise la
AbstractList
classe abstraite:Notez que si vous n'avez pas remplacé les méthodes dont vous avez besoin, les implémentations par défaut de
AbstractList
jetterontUnsupportedOperationException
s.la source
Integer maxVal = prioQueue.peek(prioQueue.size() - 1);
. Deuxièmement, si vous avez l'intention d'utiliser le PriorityQueue simplement comme une liste triée, cela semblera moins intuitif à voirPriorityQueue
dans le code qu'il ne l'aurait étéSortedList
si une telle structure de données avait existé.Collections.sort()
vous permet même de définir la fonction de comparaison utilisée pour trier, en utilisant unComparator
objet.Parce que le concept d'une Liste est incompatible avec le concept d'une collection triée automatiquement. Le point d'une liste est qu'après l'appel
list.add(7, elem)
, un appel àlist.get(7)
retourneraelem
. Avec une liste triée automatiquement, l'élément pourrait se retrouver dans une position arbitraire.la source
list.get(n)
opération sera déterministe, ce qui signifie qu'elle retournera toujours le même élément en positionn
tant que la liste n'est pas modifiée. Je ne suis pas d'accord que le "concept de liste" exige que ce soit l'ordre d'insertion. Oui, l'List
interface propose unelist.add(index, element)
méthode qui n'a pas de sens pour une collection triée, mais elle est facultative selon les documents.Étant donné que toutes les listes sont déjà "triées" par l'ordre dans lequel les articles ont été ajoutés (ordre FIFO), vous pouvez les "recentrer" avec un autre ordre, y compris l'ordre naturel des éléments, à l'aide de
java.util.Collections.sort()
.ÉDITER:
Les listes, car les structures de données sont basées sur ce qui est intéressant, c'est l'ordre dans lequel les éléments ont été insérés.
Les ensembles n'ont pas cette information.
Si vous souhaitez commander en ajoutant du temps, utilisez
List
. Si vous souhaitez commander selon d'autres critères, utilisezSortedSet
.la source
Set et Map sont une structure de données non linéaire. La liste est une structure de données linéaire.
La structure de données d'arborescence
SortedSet
et lesSortedMap
interfaces implémententTreeSet
etTreeMap
utilisent respectivement l' algorithme d'implémentation d' arbre rouge-noir utilisé. Ainsi, il s'assure qu'il n'y a pas d'articles en double (ou de clés en cas deMap
).List
maintient déjà une collection ordonnée et une structure de données basée sur un index, les arbres ne sont pas des structures de données basées sur un index.Tree
par définition, ne peut pas contenir de doublons.List
nous pouvons avoir des doublons, donc il n'y en a pasTreeList
(c'est-à-dire nonSortedList
).java.util.Collections.sort()
. Il trie la liste spécifiée par ordre croissant, selon l'ordre naturel de ses éléments.la source
JavaFX
SortedList
Bien que cela ait pris un certain temps, Java 8 a un tri
List
. http://docs.oracle.com/javase/8/javafx/api/javafx/collections/transformation/SortedList.htmlComme vous pouvez le voir dans les javadocs, il fait partie des collections JavaFX , destiné à fournir une vue triée sur une ObservableList.
Mise à jour: Notez qu'avec Java 11, la boîte à outils JavaFX s'est déplacée en dehors du JDK et est maintenant une bibliothèque distincte. JavaFX 11 est disponible en tant que SDK téléchargeable ou depuis MavenCentral. Voir https://openjfx.io
la source
Pour tous les nouveaux arrivants, depuis avril 2015, Android dispose désormais d'une classe SortedList dans la bibliothèque de support, conçue spécifiquement pour fonctionner avec
RecyclerView
. Voici le blog à ce sujet.la source
Un autre point est la complexité temporelle des opérations d'insertion. Pour une insertion de liste, on attend une complexité de O (1). Mais cela ne pouvait pas être garanti avec une liste triée.
Et le point le plus important est que les listes n'assument rien de leurs éléments. Par exemple, vous pouvez créer des listes de choses qui n'implémentent pas
equals
oucompare
.la source
SortedSet
des choses qui ne sont pas implémentéesComparable
. Voir ce constructeur TreeSet .List
interface Java ne garantit aucune spécification de performance sur ses méthodes.Pensez-y comme ceci: l'
List
interface a des méthodes commeadd(int index, E element)
,set(int index, E element)
. Le contrat est qu'une fois que vous avez ajouté un élément à la position X, vous le trouverez là, sauf si vous ajoutez ou supprimez des éléments avant lui.Si une implémentation de liste stockait des éléments dans un ordre différent de celui basé sur l'index, les méthodes de liste ci-dessus n'auraient aucun sens.
la source
La première ligne de l'API List indique qu'il s'agit d'une collection ordonnée (également appelée séquence). Si vous triez la liste, vous ne pouvez pas maintenir l'ordre, il n'y a donc pas de TreeList en Java.
Comme le dit l'API, Java List s'est inspiré de Sequence et affiche les propriétés de la séquence http://en.wikipedia.org/wiki/Sequence_(mathematics )
Cela ne signifie pas que vous ne pouvez pas trier la liste, mais Java strict à sa définition et ne fournit pas de versions triées des listes par défaut.
la source
Dans le cas où vous cherchez un moyen de trier les éléments, mais aussi d'être en mesure d'y accéder par index de manière efficace, vous pouvez faire ce qui suit:
ArrayList
)Ensuite, pour ajouter ou supprimer un élément, vous pouvez utiliser
Collections.binarySearch
pour obtenir l'index d'insertion / suppression. Étant donné que votre liste implémente l'accès aléatoire, vous pouvez modifier efficacement la liste avec l'index déterminé.Exemple:
la source
Pensez à utiliser une arborescence indexée . Il s'agit d'un TreeSet JDK amélioré qui permet d'accéder à l'élément par index et de rechercher l'index d'un élément sans itération ni listes sous-jacentes cachées qui sauvegardent l'arborescence. L'algorithme est basé sur la mise à jour des poids des nœuds changeants à chaque fois qu'il y a un changement.
la source