Dado Iterator<Element>
, como podemos converter que Iterator
a ArrayList<Element>
(ou List<Element>
) na melhor e mais rápida maneira possível, de modo que podemos usar ArrayList
's operações nele, como get(index)
, add(element)
, etc.
241
No Java 8, você pode usar o novo
forEachRemaining
método que foi adicionado àIterator
interface:fonte
::
? que nome tem isso? parece uma referência direta a list.add (); e parece também alguma coisa nova em java8; e obrigado! :)::
sintaxe é nova no Java 8 e refere-se a uma "referência de método", que é uma forma abreviada de uma lambda. Veja aqui para obter mais informações: docs.oracle.com/javase/tutorial/java/javaOO/…iterator
vem? é um símbolo não resolvidoiterator
.Você pode copiar um iterador para uma nova lista como esta:
Isso pressupõe que a lista contenha cadeias. Realmente não existe uma maneira mais rápida de recriar uma lista a partir de um iterador, você deve atravessá-la manualmente e copiar cada elemento para uma nova lista do tipo apropriado.
EDIT:
Aqui está um método genérico para copiar um iterador para uma nova lista de uma maneira segura para o tipo:
Use-o assim:
fonte
Observe que há uma diferença entre
Iterable
eIterator
.Se você possui um
Iterable
, então com o Java 8 você pode usar esta solução:Como eu sei
Collectors.toList()
criaArrayList
instância.Na verdade, na minha opinião, também fica bem em uma linha.
Por exemplo, se você precisar retornar
List<Element>
de algum método:fonte
Iterable
iterator
. Eles são completamente diferentes.Iterator
volta para um único usoIterable
usando() -> iterator
. Isso pode ser útil em situações como essa, mas deixe-me enfatizar o importante novamente: você pode usar esse método apenas se um único usoIterable
for aceitável. Ligariterable.iterator()
mais de uma vez produzirá resultados inesperados. A resposta acima é entãoIterator<Element> iterator = createIterator();
List<Element> array = StreamSupport.stream(((Iterable<Element>) () -> iterable).spliterator(), false).collect(toList());
Você também pode usar as coleções comuns
IteratorUtils
do Apache , embora ele não suporte genéricos:fonte
Solução bastante concisa com Java 8 simples usando
java.util.stream
:fonte
iterator.forEachRemaining( list::add )
, também novo no Java 8, é muito mais conciso. Pressionar a variável da lista para dentroCollector
não melhora a legibilidade nesse caso, pois ela precisa ser suportada por aStream
e aSpliterator
.fonte
Experimente
StickyList
no Cactoos :Disclaimer: Eu sou um dos desenvolvedores.
fonte
Iterable
! =Iterator
Aqui está uma lista usando Streams
fonte
Eu só quero apontar uma solução aparentemente óbvia que NÃO funcionará:
Isso porque
Stream#generate(Supplier<T>)
pode criar apenas fluxos infinitos, não espera que seu argumento seja lançadoNoSuchElementException
(é o queIterator#next()
fará no final).A resposta do xehpuk deve ser usada se a opção Iterador → Fluxo → Lista for a sua escolha.
fonte
use o google goiaba !
++
fonte
Aqui, neste caso, se você quiser o caminho mais rápido possível, então
for loop
é melhor.O iterador sobre um tamanho de amostra de
10,000 runs
takes40 ms
onde, quanto ao loop, leva2 ms
Isso pressupõe que a lista contenha cadeias.
fonte
for
loop e acessar os elementos de uma listaget(i)
é mais rápido do que usar um iterador ... mas não era isso que o OP estava pedindo, ele mencionou especificamente que um iterador é fornecido como entrada.get(int)
loop, você está olhando apenas 100k das entradas de 1m. Se você alterar esse loopit.size()
, verá que esses dois métodos estão próximos da mesma velocidade. Em geral, esses tipos de testes de velocidade do java fornecem informações limitadas sobre o desempenho na vida real e devem ser vistos com ceticismo.