São um fluxo de elementos imutáveis que podem ser processados apenas uma vez
- Pode ser sequencial ou paralela; finita ou infinita
- uma stream pode ser infinita, mas deve ter um processamento finito
- Se uma Stream tiver chamadas para
parallele outra, em qualquer ordem, parasequentialtoda a Stream será processada de acordo com o último método chamado, seja elesequentialouparallel
- As operações de uma stream utilizam functional interfaces
- São definidas através das interfaces:
BaseStream: define os comportamentos essenciaisStream: pode ser utilizada para qualquer tipo de streamDoubleStream,IntStreameLongStream: fornecem métodos que ajudam no processamento desses tipos em suas versões primitivas
- É possÃvel criar uma stream a partir de qualquer coleção, array ou com métodos estáticos da classe
Stream

Operações
Short-circuit
São algumas operações de Streams que produzem resultado finito mesmo em Streams infinitas. Existem operações short-circuit que são intermediárias ou terminais.

Intermediárias
São operações que executam uma ação e retornam outra Stream. Elas são:
filter, map, flatMap, peek, distinct, sorted, dropWhile e skip. limit, takeWhile. As operações short-circuit são: limit e takeWhile.flatMappermite transformar uma lista de listas em uma lista única, ou seja, mesclar múltiplas Streams em uma única
Terminais
São operações que percorrem toda a Stream e retornam algo diferente de uma Stream. Elas são:
forEach, ForEachOrdered, count, min, max, sum, average, collect e reduce. As operações short-circuit são: allMatch, anyMatch, noneMatch, findAny e findFirst.collectexecuta uma redução mutável nos elementos da Stream. Ele utiliza classes que implementam a interfaceCollector; existem muitos métodos auxiliares na classeCollectors
Collectors
Classe com métodos
Collector auxiliares- Existem métodos para executar cálculos matemáticos comuns
- Métodos para mapear e unir elementos de uma Stream
- Métodos de união de elementos de uma coleção
- O método
collectingAndThenune os elementos resultantes de outros métodos coletores
- O método
partitioningBydivide o conteúdo em umMapcom colunas de valores verdadeiros e falsos; um valor é testado usando umPredicate
- O método
groupingBydivide o conteúdo em umMapcom colunas criadas a partir de umaFunction

Parallel Stream Processing
Os elementos da Stream são divididos em subconjuntos. Subconjuntos podem ser divididos em mais subconjuntos, e assim por diante. Esses subconjunto são enviados para diferentes cores do processador e processados em uma ordem impossÃvel de determinar. Quando todos elementos da Stream forem processados ela se torna uma novamente.
Processamento paralelo só é benéfico se:
- A Stream tem um grande número de elementos (+10.000)
- O hardware executando o programa possuà um CPU multi-core
- O processamento feito nos elementos da Stream consome muitos recursos do CPU
Existem alguns critérios para definir se uma Stream deve ser processadas de forma paralela ou não:
- Stateless: o estado de um elemento não pode afetar outro
- Non-interfering: a coleção-fonte não deve sofrer modificações
- Associative: o resultado não pode ser afetado pela ordem de processamento dos elementos

Lidar com Streams paralelas de forma incorreta pode corromper a memória e/ou deixar o processamento lento:
- Não executar operações que precisem de acesso sequencial a um recurso compartilhado (e.g. imprimir as Strings de uma coleção)
- Não executar operações que modifiquem um recurso compartilhado (e.g. como fazer um
mapdos elementos da Stream)
- Não Usar
Collectorsinapropriados (e.g.toMapdeve ser usado em modo sequencial;toConcurrentMapem paralelo)
Â