DEV Community

FUNDAMENTOS JAVA
FUNDAMENTOS JAVA

Posted on

9.4 Operações não determinísticas e ordered streams

🔁 1. Operações não determinísticas

  • Operações como forEach e findAny não garantem ordem em parallelStream.
  • Isso pode melhorar a performance, mas o resultado pode mudar em cada execução.

📌 Exemplo com forEach (não garante ordem):

List<Integer> numeros = Arrays.asList(1, 2, 3, 4, 5); numeros.parallelStream() .forEach(System.out::print); // Pode imprimir: 23145, 51324, etc. 
Enter fullscreen mode Exit fullscreen mode

✅ Exemplo com forEachOrdered (garante ordem):

numeros.parallelStream() .forEachOrdered(System.out::print); // Sempre: 12345 
Enter fullscreen mode Exit fullscreen mode

🔍 2. findAny vs findFirst

  • findAny() retorna qualquer elemento, sem ordem garantida.
  • findFirst() sempre retorna o primeiro elemento, respeitando a ordem do stream.

🔁 Exemplo:

Optional<Integer> qualquer = numeros.parallelStream().findAny(); Optional<Integer> primeiro = numeros.parallelStream().findFirst(); 
Enter fullscreen mode Exit fullscreen mode

📌 3. Ordered vs Unordered Streams

  • Streams de listas (List, LongStream.range) são ordenados por padrão.
  • HashSet, por exemplo, não tem ordem definida.
  • Usar unordered() pode melhorar a performance em paralelismo.

🔁 Exemplo:

Set<Integer> conjunto = new HashSet<>(Arrays.asList(1, 2, 3)); conjunto.parallelStream() .unordered() .map(x -> x + 1) .forEach(System.out::println); // Pode imprimir: 4, 2, 3 
Enter fullscreen mode Exit fullscreen mode

🧩 4. Coletor agrupador paralelo

  • Collectors.groupingBy() mantém a ordem, mas pode ser lento em paralelo.
  • Collectors.groupingByConcurrent() não garante a ordem, mas é mais rápido.

🧪 Exemplo:

Map<Boolean, List<Integer>> agrupado = numeros.parallelStream() .collect(Collectors.groupingBy(i -> i % 2 == 0)); // Mantém ordem Map<Boolean, List<Integer>> agrupadoConcurrente = numeros.parallelStream() .collect(Collectors.groupingByConcurrent(i -> i % 2 == 0)); // Melhor performance 
Enter fullscreen mode Exit fullscreen mode

⚠️ 5. Efeitos colaterais e variáveis compartilhadas
Usar variáveis compartilhadas em streams paralelos pode causar resultados incorretos.
😵 Exemplo inseguro:

class UnsafeParallelStreamUsage { private static long total = 0; public static void main(String... args) { LongStream.range(0, 1_000_000_000) .parallel() .filter(x -> x % 2 == 0) .forEach(n -> total += n); // ERRO! Concorrência não segura System.out.println(total); // Resultados diferentes a cada execução } } 
Enter fullscreen mode Exit fullscreen mode

✅ Em vez disso, use sum() ou reduce() que são operações seguras:

long total = LongStream.range(0, 1_000_000_000) .parallel() .filter(x -> x % 2 == 0) .sum(); // Correto 
Enter fullscreen mode Exit fullscreen mode

🧠 6. O que é um Spliterator?

  • É uma versão moderna do Iterator, quebrável em partes.
  • Permite que várias threads processem partes diferentes do stream.
  • A paralelização do Stream se baseia nele junto com a API Fork/Join.

Classe de Exemplo completo no repo: ExemploOperacoesStreams

Top comments (0)