Можно ли перебирать массив в лямбда-выражениях? (Ява) - PullRequest
0 голосов
/ 24 октября 2019

Мне нужно сделать новый ForkJoinTask для каждого деления, и я не знаю, как добраться до следующей позиции в массиве. Кто-нибудь может мне помочь?

protected static double parManyTaskArraySum(final double[] input, final int numTasks) {

        double sum = 0;
        // ToDo: Start Calculation with help of ForkJoinPool
        ForkJoinPool fjp = new ForkJoinPool(numTasks);
        fjp.execute(() -> {

            sum+=( 1 / input[???] ); //the problem is here
        });

        return sum;
    }

Исключение: локальные переменные, на которые ссылается лямбда-выражение, должны быть окончательными или эффективно окончательными

1 Ответ

1 голос
/ 24 октября 2019

Вы кормите Runnable лямбду своему ForkJoinPool. Таким образом, вы не можете параметризовать его с нужным фрагментом массива.

На самом деле вы должны определить класс, расширяющий RecursiveTask<Double>, конструктор которого принимает кусок массива в качестве параметра и решает, следует ли работать с ним целиком или с форком, если он слишком большой.

Затем используйте метод invoke вашего ForkJoinPool, чтобы получить результат окончательного расчета, передав ему новый экземпляр этого RecursiveTask<Double>, берущий весь массив (задача будет решаться на основеваш критерий: делать ли все за один раз или, скажем, разветвлять, например, половину элементов массива на другую задачу и присоединиться позже).

Примечание , поскольку здесь есть некоторая путаница.

Если на самом деле вам не нужно использовать инфраструктуру fork / join и вы хотите выполнять только свою операцию асинхронно, существует множество способов сделать это без ForkJoinPool.

Например:

Callable<Double> call  = () -> {return Arrays.stream(input).sum();};
Future<Double> future =  Executors.newSingleThreadExecutor().submit(call);
// when you're ready
Double sum = future.get();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...