Aprimoramentos na API do Java 9 Stream

Aprimoramentos na API do Java 9 Stream

1. Visão geral

Nesta rápida descrição, vamos nos concentrar nas novas melhorias interessantes da API de Stream que vêm no Java 9.

2. Stream Takewhile / Dropwhile

Discussões sobre esses métodos apareceram repetidamente emStackOverflow (o mais popular éthis one).

Imagine que queremos gerar umStream deStrings adicionando um caractere ao valor deStream anterior até que o comprimento do valor atual nesteStream seja menor que 10.

Como resolveríamos isso no Java 8? Poderíamos usar uma das operações intermediárias de curto-circuito comolimit,allMatch que realmente servem para outros fins ou escrever nosso própriotakeWhile implementation com base em umSpliterator que, por sua vez , complica um problema tão simples.

Com o Java 9, a solução é fácil:

Stream stream = Stream.iterate("", s -> s + "s")
  .takeWhile(s -> s.length() < 10);

A operaçãotakeWhile leva umPredicate que é aplicado aos elementos para determinar o prefixo mais longo desses elementos (se um fluxo for ordenado) ou um subconjunto dos elementos do fluxo (quando um fluxo está desordenado).

Para avançar, devemos entender melhor o que os termos “o prefixo mais longo” e “um subconjuntoStream’s” significam:

  • the longest prefix é uma sequência contígua de elementos do fluxo que correspondem ao predicado fornecido. O primeiro elemento da sequência é o primeiro elemento desse fluxo, e o elemento imediatamente após o último elemento da sequência não corresponde ao predicado especificado

  • a Stream’s subset é um conjunto de alguns (mas não todos) elementos deStream que correspondem ao predicado fornecido.

Depois de introduzir esses termos-chave, podemos compreender facilmente outra nova operaçãodropWhile.

Ele faz exatamente o oposto detakeWhile. Se um fluxo é ordenado, odropWile retorna um fluxo que consiste nos elementos restantes desteStreamafter dropping the longest prefix de elementos que correspondem ao predicado fornecido.

Caso contrário, se umStream não estiver ordenado, odropWile retorna um fluxo que consiste nos elementos restantes desteStreamafter dropping a subset de elementos que correspondem ao predicado fornecido.

Vamos jogar fora os primeiros cinco elementos usando osStream obtidos anteriormente:

stream.dropWhile(s -> !s.contains("sssss"));

Simplificando, a operaçãodropWhile removerá elementos enquanto o predicado dado para um elemento retornatruee para a remoção nofalse do primeiro predicado.

3. Stream Iterate

O próximo novo recurso éthe overloaded iterate method for finite Streams generation. Não deve ser confundido com a variantefinite que retorna umStream ordenado sequencial infinito produzido por alguma função.

Um novoiterate modifica ligeiramente este método, adicionando um predicado que se aplica aos elementos para determinar quando o fluxo deve terminar. Seu uso é muito conveniente e conciso:

Stream.iterate(0, i -> i < 10, i -> i + 1)
  .forEach(System.out::println);

Pode ser associado à declaraçãofor correspondente:

for (int i = 0; i < 10; ++i) {
    System.out.println(i);
}

4. Stream Ofnullable

Existem algumas situações em que precisamos colocar um elemento em umStream. Às vezes, este elemento pode ser umnull, mas não queremos que nossoStream contenha tais valores. Isso causa a gravação de uma instruçãoif ou um operador ternário que verifica se um elemento é umnull.

Supondo que as variáveiscollectionemap, foram criadas e preenchidas com sucesso, dê uma olhada no seguinte exemplo:

collection.stream()
  .flatMap(s -> {
      Integer temp = map.get(s);
      return temp != null ? Stream.of(temp) : Stream.empty();
  })
  .collect(Collectors.toList());

Para evitar esse código clichê, o métodoofNullable foi adicionado à classeStream. Com esse método, a amostra anterior pode ser simplesmente transformada em:

collection.stream()
  .flatMap(s -> Stream.ofNullable(map.get(s)))
  .collect(Collectors.toList());

5. Conclusão

Consideramos as principais mudanças da API do Stream no Java 9 e como essas melhorias nos ajudarão a escrever programas mais enfáticos com menos esforços.

Como sempre, os trechos de código podem ser encontradosover on Github.