Supongamos que tengo un número constante de colecciones (por ejemplo, 3 ArrayLists) como miembros de una clase. Ahora, quiero exponer todos los elementos a otras clases para que simplemente puedan iterar sobre todos los elementos (idealmente, solo lectura). Estoy usando colecciones de guayaba y me pregunto cómo podría usar iterables / iteradores de guayaba para generar una vista lógica de las colecciones internas sin hacer copias temporales.
java
collections
guava
Newgre
fuente
fuente
Respuestas:
Con Guava, puede usar
Iterables.concat(Iterable<T> ...)
, crea una vista en vivo de todos los iterables, concatenados en uno (si cambia los iterables, la versión concatenada también cambia). Luego envuelva el iterable concatenado conIterables.unmodifiableIterable(Iterable<T>)
(no había visto antes el requisito de solo lectura).Desde
Iterables.concat( .. )
JavaDocs:Si bien esto no dice explícitamente que se trata de una vista en vivo, la última oración implica que lo es (admitir el
Iterator.remove()
método solo si el iterador de respaldo lo admite no es posible a menos que se use una vista en vivo)Código de muestra:
Salida:
Editar:
Por solicitud de Damian, aquí hay un método similar que devuelve una vista de colección en vivo
fuente
Iterables.unmodifiableIterable(iterable)
Iterables.concat
produce unIterable
, noCollection
. Necesitaría unaCollection
vista.size()
es lo que necesito.add()
lanzar una excepción es bueno, no me importa este método. La API de colecciones está rota y nadie puede hacer nada al respecto.Collection.add()
,Iterator.remove()
bla.Soluciones simples de Java 8 que utilizan un
Stream
.Número constante
Asumiendo
private Collection<T> c, c2, c3
.Una solución:
Otra solución:
Número variable
Asumiendo
private Collection<Collection<T>> cs
:fuente
Si está usando al menos Java 8, vea mi otra respuesta .
Si ya está utilizando Google Guava, consulte la respuesta de Sean Patrick Floyd .
Si está atascado en Java 7 y no desea incluir Google Guava, puede escribir el suyo propio (solo lectura)
Iterables.concat()
usando no más deIterable
yIterator
:Número constante
Número variable
fuente
Podrías crear uno nuevo
List
yaddAll()
de tus otrosList
al mismo. Luego devuelve una lista no modificable conCollections.unmodifiableList()
.fuente
ArrayList
simplemente asigna el espacio y las llamadasSystem.arraycopy()
bajo el capó. No puede ser mucho más eficiente que eso.Aquí está mi solución para eso:
EDITAR - código cambiado un poco
fuente
hasNext()
ynext()
. El primero cambia el estado de su iterador mientras que el segundo no lo hace. Debería ser de otra manera. Llamarnext()
sin llamarhasNext()
siempre cederánull
. LlamarhasNext()
sin llamarnext()
arrojará elementos. Tunext()
tampoco lanzaNoSuchElementException
, sino que regresanull
.