J'essayais de trouver le moyen le plus élégant d'obtenir les n éléments d'un ensemble à partir de x. Ce que j'ai conclu utilisait des flux:
Set<T> s;
Set<T> subS = s.stream().skip(x).limit(n).collect(Collectors.toSet());
Est-ce la meilleure façon de le faire de cette façon? Y a-t-il des inconvénients?
Semblable à la réponse de Steve Kuo mais en sautant les x premiers éléments:
Iterables.limit(Iterables.skip(s, x), n);
Utilisez la goyave, Iterables.limit(s, 20)
.
Votre code ne fonctionne pas.
Set<T,C> s; Set<T,C> subS = s.stream().skip(x).limit(n).collect(Collectors.toSet());
Qu'est-ce que Set<T,C>
? Une Set
contient des éléments d'un type donné, alors que sont supposés signifier les paramètres deux type?
De plus, si vous avez un Set<T>
, vous n’avez pas d’ordre défini. “Les n éléments d'un ensemble à partir de x” n'a pas de sens dans le contexte d'une Set
. Certaines implémentations Set
spécialisées ont un ordre, par exemple. sont triés ou conservent l’ordre d’insertion, mais comme votre code ne déclare pas un tel prérequis, mais semble être supposé fonctionner sur une Set
arbitraire, il doit être considéré comme rompu.
Si vous souhaitez traiter une fraction de la Set
en fonction d'une commande, vous devez d'abord geler la commande:
Set<T> s;
List<T> frozenOrder=new ArrayList<>(s);
La liste aura un ordre qui sera celui de Set
, le cas échéant, ou un ordre arbitraire, fixé au moment de la création de ArrayList
, qui ne changera pas par la suite.
Ensuite, en extraire un fragment est facile:
List<T> sub=frozenOrder.subList(x, Math.min(s.size(), x+n));
Vous pouvez également le reconvertir en une Set
, si vous le souhaitez:
Set<T> subSet=new HashSet<>(sub);
Cela dit, il est plutôt inhabituel de traiter une partie d’une Set
donnée par des nombres de position.
Un ensemble - dans sa forme originale - n'est pas destiné à avoir des éléments commandés, vous ne pouvez donc pas partir de l'élément x. SortedSet peut être le "jeu" que vous souhaitez utiliser.
Je le convertirais d'abord en liste, comme
new ArrayList(s).subList(<index of x>, <index of x + n>);
mais cela peut avoir un très mauvais impact sur les performances. Dans ce cas, la liste ArrayList devrait être stockée pour recevoir la sous-liste suivante car il n'y a pas d'ordre explicite et l'ordre implicite peut changer lors de l'appel suivant de new ArrayList(s)
.
L'utilisation de Stream
est correcte. Le seul inconvénient que je peux voir n’est pas que toutes les implémentations de Set
sont commandées HashSet
n'est pas commandé mais LinkedHashSet
l'est. SO vous pourriez obtenir un ensemble de résultats différent sur une exécution différente.
Premièrement, un ensemble n'est pas créé pour en obtenir des éléments spécifiques - vous devez plutôt utiliser un sortSet ou un tableauListe.
Mais si vous devez obtenir les éléments de l'ensemble, vous pouvez utiliser le code suivant Pour effectuer une itération sur l'ensemble:
int c = 0;
int n = 50; //Number of elements to get
Iterator<T> iter = set.iterator();
while (c<n && iter.hasNext()) {
T t = iter.next();
list.add(t);
c++;
}
Vous pouvez simplement parcourir un ensemble et collecter les n premiers éléments:
int n = 0;
Iterator<T> iter = set.iterator();
while (n < 8 && iter.hasNext()) {
T t = iter.next();
list.add(t);
n++;
}
L'avantage est que cela devrait être plus rapide que des solutions plus génériques.
L'inconvénient est que c'est plus bavard que celui que vous avez suggéré.