Atualizado: 21/09/2025

Este conteúdo é original e não foi gerado por inteligência artificial.

Métodos Paralelos em Arrays em Java

Introduzidos no JDK 8, a classe java.util.Arrays foi enriquecida com um conjunto de métodos que permitem o processamento de elementos de um array em paralelo. Esses métodos são especialmente úteis quando se trabalha com arrays grandes e a performance é crucial, como em operações de ordenação ou cálculos complexos. Diferentemente dos streams, eles atuam diretamente sobre os dados, evitando etapas intermediárias e aproveitando múltiplos núcleos de processamento para acelerar a execução.

Os principais métodos são:

  • parallelSetAll(): Preenche um array usando uma função geradora.
  • parallelSort(): Ordena um array em paralelo.
  • parallelPrefix(): Realiza um cálculo cumulativo.

Inicializando um Array com parallelSetAll()

O método parallelSetAll() é ideal para inicializar ou modificar todos os elementos de um array, onde o valor de cada elemento depende de sua posição (índice).

import java.util.Arrays;

public class ParallelSetAllExample {
    public static void main(String[] args) {
        int[] numbers = new int[6];
        // A função lambda recebe o índice 'i' e define o valor para numbers[i]
        Arrays.parallelSetAll(numbers, i -> i * 10);

        System.out.println(Arrays.toString(numbers)); // [0, 10, 20, 30, 40, 50]
    }
}

Cuidado com a Mutabilidade em parallelSetAll

Ao trabalhar com arrays de objetos, é crucial evitar a modificação direta do estado dos objetos dentro da lambda, pois isso pode levar a condições de corrida em um ambiente paralelo. A abordagem mais segura é criar novas instâncias imutáveis.

import java.util.Arrays;

record Phone(String name, int price) {
    // Retorna uma nova instância com o preço alterado (abordagem imutável)
    public Phone withPrice(int newPrice) {
        return new Phone(this.name, newPrice);
    }
}

public class ParallelSetAllObjects {
    public static void main(String[] args) {
        Phone[] phones = {
            new Phone("iPhone 15", 54000),
            new Phone("Pixel 8", 45000),
            new Phone("Samsung Galaxy S24", 40000)
        };

        // A função deve retornar o objeto que será colocado no array
        Arrays.parallelSetAll(phones, i -> {
            int currentPrice = phones[i].price();
            return phones[i].withPrice(currentPrice - 10000);
        });

        for(Phone p: phones) {
            System.out.printf("%s - %d\n", p.name(), p.price());
        }
    }
}

O resultado será:

iPhone 15 - 44000
Pixel 8 - 35000
Samsung Galaxy S24 - 30000

Ordenando um Array com parallelSort()

O método parallelSort() funciona como o Arrays.sort(), mas divide o trabalho de ordenação entre múltiplos núcleos, o que pode ser mais rápido para arrays grandes (geralmente com dezenas de milhares de elementos ou mais). Quando precisarmos de uma lógica de ordenação customizada (por exemplo, ordenar objetos complexos), podemos usar a versão sobrecarregada do método que aceita um Comparator como segundo argumento.

Vamos usar a classe Phone e criar um Comparator para ordenar os telefones pelo nome.

import java.util.Arrays;
import java.util.Comparator;

class Phone {
    private String name;
    private int price;

    public Phone(String name, int price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public int getPrice() {
        return price;
    }
}

class PhoneComparator implements Comparator<Phone> {
    public int compare(Phone a, Phone b) {
        // Usa compareToIgnoreCase para uma ordenação alfabética que ignora maiúsculas/minúsculas
        return a.getName().compareToIgnoreCase(b.getName());
    }
}

public class ParallelSortCustomExample {
    public static void main(String[] args) {
        Phone[] phones = new Phone[]{
            new Phone("iPhone 15", 54000),
            new Phone("Pixel 8", 45000),
            new Phone("Samsung Galaxy S24", 40000),
            new Phone("Nokia G42", 32000)
        };

        Arrays.parallelSort(phones, new PhoneComparator());

        for(Phone p: phones) {
            System.out.println(p.getName());
        }
    }
}

Saída:

iPhone 15
Nokia G42
Pixel 8
Samsung Galaxy S24

Cálculos Cumulativos com parallelPrefix()

O método parallelPrefix() é usado para aplicar uma operação cumulativa a um array. Em cada posição i, o novo valor será o resultado da operação entre o valor acumulado em i-1 e o valor original em i. É o análogo de "running total" ou "soma de prefixos".

Por exemplo, para calcular o produto cumulativo de uma sequência de números:

import java.util.Arrays;

public class ParallelPrefixExample {
    public static void main(String[] args) {
        int[] numbers = {1, 2, 3, 4, 5, 6};
        // A função (x, y) -> x * y é aplicada cumulativamente
        Arrays.parallelPrefix(numbers, (x, y) -> x * y);

        System.out.println(Arrays.toString(numbers)); // [1, 2, 6, 24, 120, 720]
    }
}

Para entender o que acontece, veja o passo a passo:

ÍndiceValor OriginalAcumulado AnteriorOperaçãoNovo Valor no Array
01- (nenhum)-1
121 (do índice 0)1 * 22
232 (do índice 1)2 * 36
346 (do índice 2)6 * 424
4524 (do índice 3)24 * 5120
56120 (do índice 4)120 * 6720

Resumo

  • A classe Arrays oferece métodos paralelos (parallelSetAll, parallelSort, parallelPrefix) que são alternativas eficientes aos streams para operações em arrays.
  • parallelSetAll(array, generator): Preenche um array, onde o valor de cada elemento é gerado por uma função que recebe seu índice.
  • parallelSort(array): Ordena um array em paralelo, sendo mais rápido para grandes volumes de dados. Aceita um Comparator para ordenação customizada.
  • parallelPrefix(array, operator): Modifica o array para que cada elemento contenha o resultado cumulativo de uma operação binária.
Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com