138 votes

Une implémentation de l'ensemble ordonné en Java ?

Si quelqu'un est familier avec l'Objective-C, il existe une collection appelée NSOrderedSet qui agit comme Définir et ses éléments sont accessibles comme un Array ceux de l'entreprise.

Y a-t-il quelque chose de semblable en Java ?

J'ai entendu dire qu'il y a une collection appelée LinkedHashMap mais je n'ai rien trouvé de tel pour un ensemble.

0 votes

Je travaille sur un problème similaire en c++. Avec NSOrderedSet, peut-on accéder aux éléments dans l'ordre où nous les avons insérés ?

0 votes

Savez-vous comment obtenir la fonctionnalité ci-dessus en C++ ? c'est-à-dire qu'elle agit comme SET et peut être accédée comme les éléments d'un tableau ?

163voto

Chandra Sekhar Points 5388

Jetez un coup d'œil à LinkedHashSet classe

Extrait du document Java :

Implémentation de la table de hachage et de la liste chaînée de l'interface Set, avec prédictibilité. ordre d'itération . Cette implémentation diffère de HashSet en ce qu'elle maintient une liste doublement liée passant par toutes ses entrées. Cette liste liée définit l'ordre d'itération, qui est l'ordre dans lequel les éléments ont été insérés dans l'ensemble (insertion-order) . Notez que l'ordre d'insertion n'est pas affecté si un élément est réinséré dans l'ensemble. . (Un élément e est réinséré dans un ensemble s si s.add(e) est invoqué alors que s.contains(e) renverrait vrai immédiatement avant l'invocation).

0 votes

Merci beaucoup. Il semble que ce soit trivial en regardant LinkedHashMap mais je ne l'ai pas trouvé.

3 votes

40voto

greyfairer Points 4522

Chaque Set possède un itérateur(). L'itérateur d'un HashSet normal est assez aléatoire, un TreeSet le fait par ordre de tri, un LinkedHashSet L'itérateur itère par ordre d'insertion.

En revanche, vous ne pouvez pas remplacer un élément dans un LinkedHashSet. Vous pouvez en supprimer un et en ajouter un autre, mais le nouvel élément ne sera pas à la place de l'original. Dans un LinkedHashMap, vous pouvez remplacer une valeur pour une clé existante, et les valeurs seront alors toujours dans l'ordre original.

De plus, vous ne pouvez pas insérer à une certaine position.

Vous feriez peut-être mieux d'utiliser une ArrayList avec une vérification explicite pour éviter d'insérer des doublons.

0 votes

Je veux pouvoir définir/obtenir des éléments sur une position spécifique et les obtenir dans l'ordre où je les ai ajoutés. Il semble que LinkedHashSet devrait le faire. Merci de votre réponse

16voto

Michael Borgwardt Points 181658

Jetez un coup d'œil à la Documentation sur l'API standard Java . Juste à côté de LinkedHashMap il existe un LinkedHashSet . Mais notez que l'ordre dans ceux-ci est l'ordre d'insertion, et non l'ordre naturel des éléments. Et vous ne pouvez qu'itérer dans cet ordre, sans faire d'accès aléatoire (sauf en comptant les étapes de l'itération).

Il existe également une interface SortedSet mis en œuvre par TreeSet y ConcurrentSkipListSet . Les deux permettent l'itération dans le ordre naturel de leurs éléments ou d'un Comparator mais pas l'accès aléatoire ou l'ordre d'insertion.

Pour une structure de données qui dispose à la fois d'un accès efficace par index et qui peut mettre en œuvre efficacement le critère de l'ensemble, il faudrait un liste de saut mais il n'existe aucune mise en œuvre de cette fonctionnalité dans l'API standard Java, même si je suis certain qu'il est facile d'en trouver une sur Internet.

0 votes

Je comprends peut-être mal votre commentaire, mais j'avais l'impression que, depuis Java 1.6, il existait plusieurs collections par défaut basées sur des listes de saut (comme, par exemple, ConcurrentSkipListSet etc.).

0 votes

@user988052 : oui, mais ceux-ci n'implémentent pas l'accès aléatoire par index (bien que ma compréhension des listes de saut dise que cela devrait être possible), ce qui semble être ce que Uko veut.

0 votes

@MichaelBorgwardt Java 6 et les versions ultérieures comprennent une paire d'implémentations de la liste de saut : ConcurrentSkipListMap y ConcurrentSkipListSet . Les deux gèrent un tri basé sur l'ordre naturel ou un comparateur. Je ne comprends pas s'ils fournissent l'accès aléatoire ou l'ordre d'entrée dont vous parlez.

6voto

yock Points 3729

0 votes

C'est la bonne réponse. Contrairement à LHSet, TreeSet fait implémenter java.util.SortedSet.

51 votes

Ordonné et trié sont des choses différentes. TreeSet est trié, pas ordonné

5 votes

Exactement, ordonné fait référence à l'ordre d'insertion (la façon dont une liste fonctionne), tandis que trié fait référence à l'ordre après coup des éléments en fonction de certains critères.

5voto

Essayez d'utiliser java.util.TreeSet qui met en œuvre SortedSet .

Pour citer le docteur :

"Les éléments sont ordonnés en utilisant leur ordre naturel, ou par un comparateur fourni lors de la création de l'ensemble, selon le constructeur utilisé".

Notez que l'ajout, la suppression et le contenu ont un coût en temps log(n).

Si vous voulez accéder au contenu de l'ensemble en tant que tableau, vous pouvez le convertir en faisant :

YourType[] array = someSet.toArray(new YourType[yourSet.size()]); 

Ce tableau sera trié avec les mêmes critères que le TreeSet (naturels ou par un comparateur), et dans de nombreux cas, cela aura un avantage par rapport à un Arrays.sort().

1 votes

J'ai besoin d'un ordre comme dans ArrayList, par exemple si je mets le premier élément. c et ensuite l'élément a En effet, lorsque j'itère sur une collection, je veux les obtenir dans le même ordre : c , a etc.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X