1
resposta

Como passar um arrayList para o calleble é possível?

Como passar um arrayList para o Callable é possível?

1 resposta

Fala Thiago, tudo bem ?

Não é possível passar um ArrayList para um Callable. Por padrão o método call() não recebe argumentos. Mas da pra tentar contornar de algumas formas.

Veja o exemplo onde podemos na implementação do Callable (mesmo não recebendo como parâmetro) acessar o contexto de uma lista e processar dados. No código o callable, dada uma lista original de pessoas, devolve uma lista de Strings com o primeiro nome das pessoas.

package threads;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

public class Exemplo {
    public static void main(String[] args) {

        List<Person> people = Arrays.asList(
                new Person("Rafael", "Rollo"),
                new Person("Thiago", "Mileo"));

        // inferindo pra implementação do Callable com lambda
        Callable<List<String>> task = () -> {

            // exibindo nome da thread que está atendendo (fora da main thread)
            System.out.println(Thread.currentThread().getName());

            // fazendo algo com a lista
            return people.stream()
                    .map(p -> p.getFirstName())
                    .collect(Collectors.toList());
        };

        // solicitando inicio da execução
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        Future<List<String>> names = executorService.submit(task);

        try {
            // pegando resultados que o callable devolve
            names.get().forEach(System.out::println);
        } catch (InterruptedException | ExecutionException e) {
            throw new RuntimeException("Não foi possível processar em paralelo");
        }

    }
}

class Person {
    private String firstName;
    private String lastName;

    public Person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    // getFirstName() omitido
    // getLastName() omitido
}

Aqui processamos em paralelo com a implementação do Callable (inferida a partir de uma lambda expression do java 8) que consegue acesso ao contexto da lista e ao final consumimos a Future retornada por ele pra acessar a lista resultante.

Você poderia ter uma método em uma classe ou serviço que recebe o arraylist (não o call() do Callable) e na sua implementação fazer algo parecido. Essa classe seria responsável por inferir para a implementação do Callable usando essa lista.

Existem só alguns cuidados. Perceba que apenas consumimos a lista no Callable, pois ela deve ser efetivamente final, ou seja, não podemos alterar sua referência. Em geral usaria maps, filters, reduces tudo que use a lista original e origine listas resultantes sem alterar o estado da original.

Acho que você poderia pensar em algo assim. Espero ter ajudado no pensamento. Abraço!

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software