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
parallel
e outra, em qualquer ordem, parasequential
toda a Stream será processada de acordo com o último método chamado, seja elesequential
ouparallel
- 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
,IntStream
eLongStream
: 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
.flatMap
permite 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
.collect
executa 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
collectingAndThen
une os elementos resultantes de outros métodos coletores
- O método
partitioningBy
divide o conteúdo em umMap
com colunas de valores verdadeiros e falsos; um valor é testado usando umPredicate
- O método
groupingBy
divide o conteúdo em umMap
com 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
map
dos elementos da Stream)
- Não Usar
Collectors
inapropriados (e.g.toMap
deve ser usado em modo sequencial;toConcurrentMap
em paralelo)
Â