En mi aplicación utilizo una biblioteca de terceros (Spring Data para MongoDB para ser exactos).
Los métodos de esta biblioteca regresan Iterable<T>
, mientras que el resto de mi código espera Collection<T>
.
¿Hay algún método de utilidad en algún lugar que me permita convertir rápidamente uno a otro? Me gustaría evitar crear un montón de foreach
bucles en mi código para algo tan simple.
java
collections
Ula Krukar
fuente
fuente
Respuestas:
Con Guava puede usar Lists.newArrayList (Iterable) o Sets.newHashSet (Iterable) , entre otros métodos similares. Por supuesto, esto copiará todos los elementos en la memoria. Si eso no es aceptable, creo que su código que funciona con estos debería tomar en
Iterable
lugar deCollection
. La guayaba también proporciona métodos convenientes para hacer cosas que puede hacerCollection
usando unIterable
(comoIterables.isEmpty(Iterable)
oIterables.contains(Iterable, Object)
), pero las implicaciones de rendimiento son más obvias.fuente
Lists.newArrayList(Iterable).clear()
una operación de tiempo lineal o constante?Collection
no se pueden implementar para una vistaIterable
o no serán eficientes, no tiene mucho sentido hacerlo.Iterables.concat()
pero eso da unIterable
, no unCollection
:(Iterables.concat()
. La respuesta mucho más larga daCollection
... Me pregunto por qué esto no es más comúnmente compatible.En JDK 8+, sin usar ninguna biblioteca adicional:
Editar: El anterior es para
Iterator
. Si se trata deIterable
,fuente
iterable.forEach(target::add);
También puede escribir su propio método de utilidad para esto:
fuente
Iterable
aCollection
es la única preocupación, preferiría este enfoque a importar una gran biblioteca de colecciones de terceros.Solución concisa con Java 8 usando
java.util.stream
:fuente
IteratorUtils
decommons-collections
IteratorUtils.toList()
usa el iterador de una manera previa a Java 5 para agregar los elementos uno por uno a una lista recién creada. Simple y posiblemente más rápido, pero agrega 734 kB a su binario y podría hacerlo por su cuenta si considera que este método es el mejor.IteratorUtils
decommons-collections
ayudar a mayo (a pesar de que no son compatibles con los genéricos en la última versión estable 3.2.1):La versión 4.0 (que está en SNAPSHOT en este momento) admite genéricos y puede deshacerse de ellos
@SuppressWarnings
.Actualización: Verificación
IterableAsList
de Cactoos .fuente
IterableUtils.toList(Iterable)
, que es un método conveniente y se utilizaIteratorUtils
debajo del capó, pero también es nulo seguro (a diferenciaIteratorUtils.toList
).De CollectionUtils :
Aquí están las fuentes completas de este método de utilidad:
fuente
Lists.newArrayList(someIterable).clear()
una operación de tiempo lineal o constante?addAll
, como su nombre lo indica, copia los valores del iterador uno tras otro; crea una copia en lugar de una vista.CollectionUtils
para omitir la creación de la colección en una línea adicional.Mientras lo hace, no olvide que todas las colecciones son finitas, mientras que Iterable no tiene promesas de ningún tipo. Si algo es Iterable, puede obtener un Iterator y eso es todo.
se ampliará a:
it.hasNext () no está obligado a devolver false. Por lo tanto, en el caso general, no puede esperar poder convertir cada Iterable en una Colección. Por ejemplo, puede iterar sobre todos los números naturales positivos, iterar sobre algo con ciclos que produzca los mismos resultados una y otra vez, etc.
De lo contrario: la respuesta de Atrey está bastante bien.
fuente
Yo uso
FluentIterable.from(myIterable).toList()
muchofuente
Esta no es una respuesta a su pregunta, pero creo que es la solución a su problema. La interfaz
org.springframework.data.repository.CrudRepository
tiene métodos que regresan,java.lang.Iterable
pero no debe usar esta interfaz. En su lugar, use sub interfaces, en su casoorg.springframework.data.mongodb.repository.MongoRepository
. Esta interfaz tiene métodos que devuelven objetos de tipojava.util.List
.fuente
Uso mi utilidad personalizada para emitir una Colección existente si está disponible.
Principal:
Idealmente, lo anterior usaría ImmutableList, pero ImmutableCollection no permite valores nulos que pueden proporcionar resultados no deseados.
Pruebas:
Implemento utilidades similares para todos los subtipos de Colecciones (Conjunto, Lista, etc.). Creo que estos ya serían parte de Guava, pero no lo he encontrado.
fuente
Tan pronto como usted lo llama
contains
,containsAll
,equals
,hashCode
,remove
,retainAll
,size
otoArray
, tendría que atravesar los elementos de todos modos.Si ocasionalmente solo llama a métodos como
isEmpty
oclear
supongo que sería mejor crear la colección de manera perezosa. Por ejemplo, podría tener un respaldoArrayList
para almacenar elementos iterados previamente.No conozco ninguna clase de este tipo en ninguna biblioteca, pero debería ser un ejercicio bastante simple de escribir.
fuente
En Java 8 puede hacer esto para agregar todos los elementos de un
Iterable
toCollection
y devolverlo:Inspirado por la respuesta de @Afreys.
fuente
Como RxJava es un martillo y parece un clavo, puedes hacer
fuente
Aquí hay un SSCCE para una excelente manera de hacer esto en Java 8
fuente
Encontré una situación similar al intentar obtener una
List
deProject
s, en lugar del valor predeterminadoIterable<T> findAll()
declarado en laCrudRepository
interfaz. Entonces, en miProjectRepository
interfaz (que se extiende desdeCrudRepository
), simplemente declaró que elfindAll()
método devolvería un enList<Project>
lugar deIterable<Project>
.Esta es la solución más simple, creo, sin requerir la lógica de conversión o el uso de bibliotecas externas.
fuente
Dos observaciones
fuente
Probar
StickyList
de Cactoos :fuente
No vi una solución simple de una línea sin ninguna dependencia. Yo uso simple
fuente
Puede usar las fábricas de Eclipse Collections :
También puede convertir
Iterable
a ayLazyIterable
usar los métodos de conversión o cualquiera de las otras API disponibles disponibles.Todos los
Mutable
tipos anteriores se extiendenjava.util.Collection
.Nota: Soy un committer para Eclipse Collections.
fuente