Fluxos de tipo primitivo em Java 8

Fluxos de tipo primitivo em Java 8

*1. Introdução *

A API Stream foi um dos principais recursos adicionados no Java 8.

Resumidamente, a API nos permite processar coleções e outras seqüências de elementos - link:/java-8-streams [de forma conveniente e mais eficiente] - fornecendo uma API declarativa.

===* 2. Fluxos primitivos *

Os fluxos trabalham principalmente com coleções de objetos e não com tipos primitivos.

Felizmente, para fornecer uma maneira de trabalhar com os três tipos primitivos mais usados ​​- int, long e double - a biblioteca padrão inclui três implementações especializadas em primitivos: IntStream, LongStream, _ e _DoubleStream.

Os fluxos primitivos são limitados principalmente por causa da sobrecarga do boxe e porque a criação de fluxos especializados para outros primitivos não é 'tão útil em muitos casos.

===* 3. Operaçoes aritimeticas *

Vamos começar com alguns métodos interessantes para operações aritméticas muito usadas, como min, max, sum e _average: _

int[] integers = new int[] {20, 98, 12, 7, 35};
int min = Arrays.stream(integers)
  .min()
  .getAsInt();//returns 7

Vamos agora percorrer o snippet de código acima para entender o que está acontecendo.

Criamos nosso IntStream usando java.util.Arrays.stream (int []) _ e, em seguida, usamos o método _min () _ para obter o número inteiro mais baixo como _java.util.OptionalInt e, finalmente, chamamos getAsInt () _ para obter o _int valor.

Outra maneira de criar um IntStream é usando _IntStream.of (int…) _. O método _max () _ retornará o maior número inteiro:

int max = IntStream.of(20, 98, 12, 7, 35)
  .max()
  .getAsInt();//returns 98

Em seguida - para obter a soma dos números inteiros, basta chamar o método sum () _ e não precisamos usar _getAsInt () _, pois ele já retorna o resultado como um valor _int:

int sum = IntStream.of(20, 98, 12, 7, 35).sum();//returns 172

Invocamos o método average () _ para obter a média dos valores inteiros e, como podemos ver, devemos usar _getAsDouble () _, pois ele retorna um valor do tipo _double.

double avg = IntStream.of(20, 98, 12, 7, 35)
  .average()
  .getAsDouble();//returns 34.4

===* 4. Alcance *

Também podemos criar um IntStream com base em um intervalo:

int sum = IntStream.range(1, 10)
  .sum();//returns 45
int sum = IntStream.rangeClosed(1, 10)
  .sum();//returns 55

Como o snippet de código acima mostra, há duas maneiras de criar um intervalo de valores inteiros _range () _ e _rangeClosed () _.

A diferença é que o final de _range () _ é exclusivo enquanto inclusivo em _rangeClosed () _.

Os métodos de intervalo estão disponíveis apenas para IntStream e LongStream.

Podemos usar range como uma forma elegante de um loop for-each:

IntStream.rangeClosed(1, 5)
  .forEach(System.out::println);

O que é bom em usá-los como uma substituição para cada loop é que também podemos tirar proveito da execução paralela:

IntStream.rangeClosed(1, 5)
  .parallel()
  .forEach(System.out::println);

Por mais úteis que sejam esses loops sofisticados, ainda é melhor usar os for-loops tradicionais em vez do funcional para iterações simples devido à simplicidade, legibilidade e desempenho em alguns casos.

===* 5. Boxe e Unboxing *

Há momentos em que precisamos converter valores primitivos em seus equivalentes de invólucro.

Nesses casos, podemos usar o método _boxed () _:

List<Integer> evenInts = IntStream.rangeClosed(1, 10)
  .filter(i -> i % 2 == 0)
  .boxed()
  .collect(Collectors.toList());

Também podemos converter do fluxo da classe wrapper para o fluxo primitivo:

//returns 78
int sum = Arrays.asList(33,45)
  .stream()
  .mapToInt(i -> i)
  .sum();

Sempre podemos usar os métodos mapToXxx e flatMapToXxx para criar fluxos primitivos.

===* 6. Conclusão*

O Java Streams é uma adição muito poderosa à linguagem. Mal arranhamos a superfície dos fluxos primitivos aqui, mas como você já pode usá-los para ser produtivo.

E, como sempre, exemplos de código podem ser encontrados over no GitHub.