Supposons que j'ai un nombre constant de collections (par exemple 3 ArrayLists) en tant que membres d'une classe. Maintenant, je veux exposer tous les éléments à d'autres classes afin qu'ils puissent simplement itérer sur tous les éléments (idéalement, en lecture seule). J'utilise des collections de goyave et je me demande comment je pourrais utiliser les itérables / itérateurs de goyave pour générer une vue logique sur les collections internes sans faire de copies temporaires.
java
collections
guava
Newgre
la source
la source
Réponses:
Avec Guava, vous pouvez utiliser
Iterables.concat(Iterable<T> ...)
, il crée une vue en direct de tous les itérables, concaténés en un (si vous modifiez les itérables, la version concaténée change également). Ensuite, enveloppez l'itérable concaténé avecIterables.unmodifiableIterable(Iterable<T>)
(je n'avais pas vu l'exigence en lecture seule auparavant).À partir des
Iterables.concat( .. )
JavaDocs:Bien que cela ne dise pas explicitement qu'il s'agit d'une vue en direct, la dernière phrase implique que c'est le cas (prendre en charge la
Iterator.remove()
méthode uniquement si l'itérateur de support le prend en charge, ce n'est pas possible à moins d'utiliser une vue en direct)Exemple de code:
Production:
Éditer:
À la demande de Damian, voici une méthode similaire qui renvoie une vue de collection en direct
la source
Iterables.unmodifiableIterable(iterable)
Iterables.concat
produit unIterable
, nonCollection
. J'aurais besoin d'uneCollection
vue.size()
c'est ce dont j'ai besoin.add()
lancer une exception, c'est bien - je me fiche de cette méthode. L'API Collections est cassée et personne ne peut rien y faire.Collection.add()
,Iterator.remove()
, Bla.Solutions Java 8 simples utilisant un fichier
Stream
.Nombre constant
En supposant
private Collection<T> c, c2, c3
.Une solution:
Une autre solution:
Numéro de variable
En supposant
private Collection<Collection<T>> cs
:la source
Si vous utilisez au moins Java 8, consultez mon autre réponse .
Si vous utilisez déjà Google Guava, consultez la réponse de Sean Patrick Floyd .
Si vous êtes bloqué sur Java 7 et que vous ne souhaitez pas inclure Google Guava, vous pouvez écrire le vôtre (en lecture seule) en
Iterables.concat()
n'utilisant pas plus deIterable
etIterator
:Nombre constant
Numéro de variable
la source
Vous pouvez créer un nouveau
List
etaddAll()
de vos autresList
à lui. Puis renvoyez une liste non modifiable avecCollections.unmodifiableList()
.la source
ArrayList
allouent simplement l'espace et les appelsSystem.arraycopy()
sous le capot. Je ne peux pas être beaucoup plus efficace que ça.Voici ma solution pour cela:
EDIT - code un peu changé
la source
hasNext()
etnext()
. Le premier change l'état de votre itérateur alors que le second ne change pas. Il devrait être l'inverse. Appelernext()
sans appelerhasNext()
cédera toujoursnull
. AppelerhasNext()
sans appelernext()
jettera des éléments. Votrenext()
ne lance pas nonNoSuchElementException
plus, mais revient à la placenull
.