Suponha que eu tenho um número constante de coleções (por exemplo, 3 ArrayLists) como membros de uma classe. Agora, quero expor todos os elementos a outras classes para que possam simplesmente iterar sobre todos os elementos (de preferência, somente leitura). Estou usando coleções de goiaba e me pergunto como poderia usar iteráveis / iteradores de goiaba para gerar uma visão lógica nas coleções internas sem fazer cópias temporárias.
java
collections
guava
Newgre
fonte
fonte
Respostas:
Com o Guava, você pode usar o
Iterables.concat(Iterable<T> ...)
, ele cria uma visualização ao vivo de todos os iteráveis, concatenados em um (se você alterar os iteráveis, a versão concatenada também muda). Em seguida, envolva o iterável concatenado comIterables.unmodifiableIterable(Iterable<T>)
(eu não tinha visto o requisito somente leitura antes).Dos
Iterables.concat( .. )
JavaDocs:Embora isso não diga explicitamente que se trata de uma visualização ao vivo, a última frase implica que é (suportar o
Iterator.remove()
método apenas se o iterador de apoio oferecer suporte, não é possível, a menos que use uma visualização ao vivo)Código de amostra:
Resultado:
Editar:
Por solicitação de Damian, aqui está um método semelhante que retorna uma visualização de coleção ao vivo
fonte
Iterables.unmodifiableIterable(iterable)
Iterables.concat
produz umIterable
, nãoCollection
. Eu precisaria de umaCollection
visão.size()
é o que eu preciso.add()
lançar uma exceção é bom - eu não me importo com esse método. A API de coleções está quebrada e ninguém pode fazer nada a respeito.Collection.add()
,Iterator.remove()
, Blá.Soluções simples do Java 8 usando a
Stream
.Número constante
Supondo
private Collection<T> c, c2, c3
.Uma solução:
Outra solução:
Número variável
Supondo
private Collection<Collection<T>> cs
:fonte
Se você estiver usando pelo menos Java 8, veja minha outra resposta .
Se você já usa o Google Guava, veja a resposta de Sean Patrick Floyd .
Se você estiver travado no Java 7 e não quiser incluir o Google Guava, poderá escrever o seu próprio (somente leitura)
Iterables.concat()
usando no máximoIterable
eIterator
:Número constante
Número variável
fonte
Você poderia criar um novo
List
eaddAll()
de seus outrosList
para ele. Em seguida, retorne uma lista não modificável comCollections.unmodifiableList()
.fonte
ArrayList
apenas alocam o espaço e as chamadasSystem.arraycopy()
sob o capô. Não pode ser muito mais eficiente do que isso.Aqui está minha solução para isso:
EDIT - código alterado um pouco
fonte
hasNext()
enext()
. O primeiro muda o estado do seu iterador, enquanto o segundo não. Deveria ser o contrário. Chamarnext()
sem chamarhasNext()
sempre renderánull
. ChamarhasNext()
sem chamarnext()
jogará elementos fora. Vocênext()
também não jogaNoSuchElementException
, mas retornanull
.