Quais são as diferenças entre Streams, Views (SeqView) e Iterators no scala? Este é o meu entendimento:
- São todas listas preguiçosas.
- Os fluxos armazenam em cache os valores.
- Iteradores podem ser usados apenas uma vez? Você não pode voltar ao início e avaliar o valor novamente?
- Os valores da visualização não são armazenados em cache, mas você pode avaliá-los repetidamente?
Portanto, se eu quiser economizar espaço de heap, devo usar iteradores (se não percorrer a lista novamente) ou visualizações? Obrigado.
Respostas:
Primeiro, eles são todos não rigorosos . Isso tem um significado matemático específico relacionado às funções, mas, basicamente, significa que elas são computadas sob demanda e não antecipadamente.
Stream
é realmente uma lista preguiçosa. De fato, em Scala, aStream
é umList
cujotail
é alazy val
. Uma vez calculado, um valor permanece calculado e é reutilizado. Ou, como você diz, os valores são armazenados em cache.Um
Iterator
só pode ser usado uma vez porque é um ponteiro transversal para uma coleção, e não uma coleção em si. O que o torna especial em Scala é o fato de que você pode aplicar de transformação, comomap
efilter
e simplesmente obter um novoIterator
que só irá aplicar essas transformações quando você perguntar para o próximo elemento.O Scala costumava fornecer iteradores que poderiam ser redefinidos, mas isso é muito difícil de suportar de uma maneira geral, e eles não criaram a versão 2.8.0.
As visualizações devem ser vistas como uma exibição de banco de dados. É uma série de transformação que se aplica a uma coleção para produzir uma coleção "virtual". Como você disse, todas as transformações são reaplicadas sempre que você precisar buscar elementos nela.
Ambas as
Iterator
visualizações e têm excelentes características de memória.Stream
é bom, mas, em Scala, seu principal benefício é escrever sequências infinitas (particularmente sequências definidas recursivamente). Um pode evitar manter todas asStream
na memória, no entanto, por ter certeza que você não manter uma referência ao seuhead
(por exemplo, usandodef
em vez deval
definir oStream
).Por causa das penalidades incorridas pelas visualizações, geralmente
force
é necessário após a aplicação das transformações, ou mantê-la como uma visualização, se é esperado que apenas alguns elementos sejam buscados, em comparação com o tamanho total da visualização.fonte
Iterator
também é bastante útil para investigar o infinito, e geralmente os prefiro sobre fluxos sempre que possível. O benefício real nos fluxos é que os valores acessados anteriormente são armazenados em cache, o que é um benefício sério ao tentar implementar algo como a sequência de fibonacci - que é definida em termos de valores anteriores.