J'essaie de trouver une implémentation de java.util.List
et java.util.Set
en même temps en Java. Je veux que cette classe autorise uniquement les éléments uniques (as Set
) et conserve leur ordre (like List
). Existe-t-il dans JDK 6?
C'est important d'avoir List<T>#add(int, T)
pour que je puisse m'insérer dans une position spécifique.
java
collections
yegor256
la source
la source
Comparator
? Voulez-vous également la sémantique de l'List
interface?Réponses:
TreeSet
est trié par ordre d'élément;LinkedHashSet
conserve l'ordre d'insertion. J'espère que l'un de ceux-là est ce que vous recherchiez.Vous avez spécifié que vous voulez pouvoir insérer à un emplacement arbitraire , je suppose que vous devrez écrire le vôtre - créez simplement une classe contenant un
HashSet<T>
et unArrayList<T>
; lors de l'ajout d'un élément, vérifiez s'il fait partie de l'ensemble avant de l'ajouter à la liste.Alternativement, les offres commons-collections4 d'Apache
ListOrderedSet
etSetUniqueList
, qui se comportent de la même manière et doivent répondre aux exigences données.la source
LinkedHashSet est la réponse.
Ordre des itérations et unicité.
http://download.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html
la source
List
Voulez-vous dire comme
LinkedHashSet
? Cela préserve l'ordre d'entrée, mais n'autorise pas les doublons.IMHO, c'est une exigence inhabituelle mais vous pouvez écrire une liste sans doublons.
class SetList<T> extends ArrayList<T> { @Override public boolean add(T t) { return !super.contains(t) && super.add(t); } @Override public void add(int index, T element) { if (!super.contains(element)) super.add(index, element); } @Override public boolean addAll(Collection<? extends T> c) { boolean added = false; for (T t : c) added |= add(t); return added; } @Override public boolean addAll(int index, Collection<? extends T> c) { boolean added = false; for (T t : c) if (!super.contains(t)) { super.add(index++, t); added = true; } return added; } }
la source
List
O(n)
complexité d'insertion, il y a un compromis à considérer entre le double stockage et l'O(log(n))
opération d'insertion.Vous ne pouvez pas mettre en œuvre
List
etSet
à la fois sans violation du contrat. Voir, par exemple, leSet.hashCode
contrat:En revanche voici le contrat de
List.hashCode
:Il est donc impossible d'implémenter une classe unique qui garantit que les deux contrats seront remplis. Le même problème pour la
equals
mise en œuvre.la source
Si vous ne vous limitez pas au JDK 6, vous pouvez utiliser la bibliothèque de collections commune Apache qui offre une correspondance exacte pour vos besoins - ListOrderedSet . C'est comme
List
etSet
combiné ensemble :)la source
List
interfaceJ'ai eu un problème similaire, alors j'ai écrit le mien. Regardez ici . L'
IndexedArraySet
extensionArrayList
et les implémentationsSet
, il doit donc prendre en charge toutes les opérations dont vous avez besoin. Notez que l'insertion d'éléments dans des emplacements au milieu d'unArrayList
peut être lente pour les grandes listes car tous les éléments suivants doivent être déplacés. MonIndexedArraySet
ne change pas ça.la source
Une autre option (moins l'
List
exigence d'interface) est celle de GuavaImmutableSet
, qui préserve l'ordre d'insertion. Depuis leur page wiki :la source