Dans mon application, j'utilise une bibliothèque tierce (Spring Data pour MongoDB pour être exact).
Les méthodes de cette bibliothèque reviennent Iterable<T>
, tandis que le reste de mon code attend Collection<T>
.
Existe-t-il une méthode utilitaire quelque part qui me permette de convertir rapidement l'une en l'autre? Je voudrais éviter de créer un tas de foreach
boucles dans mon code pour une chose aussi simple.
java
collections
Ula Krukar
la source
la source
Réponses:
Avec Guava, vous pouvez utiliser Lists.newArrayList (Iterable) ou Sets.newHashSet (Iterable) , entre autres méthodes similaires. Cela copiera bien sûr tous les éléments dans la mémoire. Si ce n'est pas acceptable, je pense que votre code qui fonctionne avec ceux-ci devrait prendre
Iterable
plutôt queCollection
. La goyave fournit également des méthodes pratiques pour faire des choses que vous pouvez faire sur un enCollection
utilisant unIterable
(commeIterables.isEmpty(Iterable)
ouIterables.contains(Iterable, Object)
), mais les implications en termes de performances sont plus évidentes.la source
Lists.newArrayList(Iterable).clear()
une opération à temps linéaire ou constant?Collection
ou l'autre ne peuvent pas être implémentées pour une vue d'unIterable
ou ne seront pas efficaces, cela n'a pas beaucoup de sens pour moi de le faire.Iterables.concat()
mais cela donne unIterable
, pas unCollection
:(Iterables.concat()
. La réponse beaucoup plus longue donneCollection
... Je me demande pourquoi ce n'est pas plus couramment pris en charge?Dans JDK 8+, sans utiliser de bibliothèques supplémentaires:
Edit: Celui ci-dessus est pour
Iterator
. Si vous avez affaire àIterable
,la source
iterable.forEach(target::add);
Vous pouvez également écrire votre propre méthode utilitaire pour cela:
la source
Iterable
àCollection
est la seule préoccupation, je préférerais cette approche à l'importation d'une grande bibliothèque de collections tierces.Solution concise avec Java 8 utilisant
java.util.stream
:la source
IteratorUtils
decommons-collections
IteratorUtils.toList()
utilise l'itérateur avant Java 5 pour ajouter les éléments un par un à une liste nouvellement créée. Simple et peut-être plus rapide, mais ajoute 734 Ko à votre binaire et vous pouvez le faire vous-même si vous trouvez que cette méthode est la meilleure.IteratorUtils
fromcommons-collections
peut aider (bien qu'ils ne prennent pas en charge les génériques dans la dernière version stable 3.2.1):La version 4.0 (qui est actuellement dans SNAPSHOT) prend en charge les génériques et vous pouvez vous en débarrasser
@SuppressWarnings
.Mise à jour: Vérifiez
IterableAsList
auprès de Cactoos .la source
IterableUtils.toList(Iterable)
, qui est une méthode pratique et utiliseIteratorUtils
sous le capot, mais est également sans danger (contrairementIteratorUtils.toList
).De CollectionUtils :
Voici les sources complètes de cette méthode utilitaire:
la source
Lists.newArrayList(someIterable).clear()
une opération à temps linéaire ou constant?addAll
, comme son nom l'indique, il copie les valeurs de l'itérateur les unes après les autres; il crée une copie plutôt qu'une vue.CollectionUtils
pour ignorer la création de la collection dans une ligne supplémentaire.Pendant que vous y êtes, n'oubliez pas que toutes les collections sont finies, alors que Iterable n'a aucune promesse. Si quelque chose est itérable, vous pouvez obtenir un itérateur et c'est tout.
sera étendu à:
it.hasNext () n'est pas obligé de renvoyer false. Ainsi, dans le cas général, vous ne pouvez pas vous attendre à pouvoir convertir chaque Iterable en une collection. Par exemple, vous pouvez itérer sur tous les nombres naturels positifs, itérer sur quelque chose avec des cycles qui produisent les mêmes résultats encore et encore, etc.
Sinon: la réponse d'Atrey est assez bonne.
la source
J'utilise
FluentIterable.from(myIterable).toList()
beaucoup.la source
Ce n'est pas une réponse à votre question mais je crois que c'est la solution à votre problème. L'interface a en
org.springframework.data.repository.CrudRepository
effet des méthodes qui retournentjava.lang.Iterable
mais vous ne devez pas utiliser cette interface. Utilisez plutôt des sous-interfaces, dans votre casorg.springframework.data.mongodb.repository.MongoRepository
. Cette interface possède des méthodes qui renvoient des objets de typejava.util.List
.la source
J'utilise mon utilitaire personnalisé pour caster une collection existante si disponible.
Principale:
Idéalement, ce qui précède utiliserait ImmutableList, mais ImmutableCollection ne permet pas les valeurs nulles qui peuvent fournir des résultats indésirables.
Tests:
J'implémente des utilitaires similaires pour tous les sous-types de collections (Set, List, etc.). Je pense que ceux-ci feraient déjà partie de la goyave, mais je ne l'ai pas trouvé.
la source
Dès que vous appelez
contains
,containsAll
,equals
,hashCode
,remove
,retainAll
,size
outoArray
, vous auriez à traverser les éléments de toute façon.Si vous n'appelez occasionnellement que des méthodes telles que
isEmpty
ouclear
je suppose que vous feriez mieux de créer la collection paresseusement. Vous pouvez par exemple avoir un supportArrayList
pour stocker des éléments précédemment itérés.Je ne connais aucune de ces classes dans aucune bibliothèque, mais ce devrait être un exercice assez simple à rédiger.
la source
En Java 8 , vous pouvez le faire pour ajouter tous les éléments d'un
Iterable
àCollection
et le retourner:Inspiré par la réponse @Afreys.
la source
Depuis RxJava est un marteau et cela ressemble un peu à un clou, vous pouvez le faire
la source
Voici un SSCCE pour un excellent moyen de le faire dans Java 8
la source
Je suis tombé sur une situation similaire en essayant de récupérer un
List
deProject
s, plutôt que la valeur par défautIterable<T> findAll()
déclarée dans l'CrudRepository
interface. Donc, dans monProjectRepository
interface (qui s'étend deCrudRepository
), j'ai simplement déclaré lafindAll()
méthode pour retourner unList<Project>
au lieu deIterable<Project>
.C'est la solution la plus simple, je pense, sans nécessiter de logique de conversion ni d'utilisation de bibliothèques externes.
la source
Deux remarques
la source
Essayez
StickyList
avec Cactoos :la source
Je n'ai pas vu de solution simple sur une seule ligne sans aucune dépendance. J'utilise simplement
la source
Vous pouvez utiliser les usines Eclipse Collections :
Vous pouvez également convertir le fichier
Iterable
en unLazyIterable
et utiliser les méthodes de conversion ou l'une des autres API disponibles disponibles.Tous les
Mutable
types ci-dessus s'étendentjava.util.Collection
.Remarque: je suis un committer pour les collections Eclipse.
la source