Сумма элементов N массивов, использующих Java 8 Stream - PullRequest
0 голосов
/ 02 апреля 2020

Я могу иметь N массивов разной длины. Важная вещь в том, что я не знаю, сколько у меня может быть массивов. Давайте рассмотрим пример с тремя массивами:

Integer arr1[] = {5, 10, -5};
Integer arr2[] = {8, 3};
Integer arr3[] = {12, -1, 0, 9};

List<String> result = Arrays.stream(arr1)
        .flatMap(s1 -> Arrays.stream(arr2)
                .flatMap(s2 -> Arrays.stream(arr3)
                        .map(s3 -> s1 + s2 + s3)))
        .collect(Collectors.toList());

Можно ли сделать такое для N Arrays, используя Stream?

Вот, ребята. Еще один пример с ожидаемым результатом

 Integer arr1[] = {2, 4, 5};
 Integer arr2[] = {2, 4, 5};
 Integer arr3[] = {2 , 4, 5};

 List<Integer> result = Arrays.stream(arr1)
                .flatMap(s1 -> Arrays.stream(arr2)
                .flatMap(s2 -> Arrays.stream(arr3)
                .map(s3 -> s1 + s2 + s3))).sorted().collect(Collectors.toList());

                 System.out.println(" List of results: "+result);


              // List of results: [6, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15]

Ответы [ 3 ]

0 голосов
/ 02 апреля 2020

Это не ясно из вашего вопроса, что вы хотите. Таким образом, мы можем только угадать вашу проблему и угадать решение. Пожалуйста, опишите в словах, что вы хотите сделать. Если ваш код в основном неверен, вы можете ожидать, что люди будут давать неправильные решения. Похоже, вы хотите узнать сумму N массивов. Если да, то вот решение.

import java.util.Arrays;
import java.util.stream.Stream;

public class Temp {
    public static void main(String[] args) {
        Integer arr1[] = {5, 10, -5};
        Integer arr2[] = {8, 3};
        Integer arr3[] = {12, -1, 0, 9};

        System.out.println(doSomething(arr1, arr2, arr3));
    }

    public static Integer doSomething(Integer [] ... arrays){
        Integer sumOfArrays = Stream.of(arrays)
                .map( array -> Arrays.stream(array)
                        .reduce(0, (sum, nextInt) -> sum + nextInt )
                ).reduce( 0, (allArraySum, arraySum) -> allArraySum + arraySum );
        return sumOfArrays;
    }
}
0 голосов
/ 02 апреля 2020

Если вы хотите получить сумму всех целых чисел в массивах, вы можете сделать это следующим образом:

int sumOfAll = Stream.of(arr1, arr2, arr3)
    .flatMap(Arrays::stream)
    .mapToInt(v -> v)
    .sum();

Если вам нужен список с суммой целых чисел в данной позиции, то вы можете сделать это следующим образом. Вычислить максимальную длину в массивах и затем использовать ее для вставки значения по умолчанию, если текущий список слишком мал.

int max = Stream.of(arr1, arr2, arr3).mapToInt(a -> a.length).max().getAsInt();

List<Integer> reduce = Stream.of(arr1, arr2, arr3)
    .map(a -> Stream.of(a).collect(toList()))
    .reduce((a, b) -> IntStream.range(0, max)
        .mapToObj(i -> (i < a.size() ? a.get(i) : 0) + (i < b.size() ? b.get(i) : 0))
        .collect(toList()))
    .get();

ОБНОВЛЕНИЕ

Если вы хотите добиться того, что вы показали во втором примере, тогда можно сделать как ниже.

  • Создать List<List<Integer>>, который собирает все необходимые для суммирования числа.
  • Выполните операцию суммирования для каждого списка.
List<List<Integer>> integersList = Stream.of(arr11, arr12, arr13)
        .map(a -> Stream.of(a).map(x -> Arrays.asList(x)).collect(toList()))
        .reduce((a, b) -> b.stream().flatMap(v -> a.stream()
                        .map(x -> {
                                    ArrayList<Integer> ints = new ArrayList<>(x);
                                    ints.add(v.get(0));
                                    return ints;
                                }
                        )
                ).collect(toList())
        ).get();

Это дает:

[[2, 2, 2], [4, 2, 2], [5, 2, 2], [2, 4, 2], [4, 4, 2 ], [5, 4, 2], [2, 5, 2], [4, 5, 2], [5, 5, 2], [2, 2, 4], [4, 2, 4], [5, 2, 4], [2, 4, 4], [4, 4, 4], [5, 4, 4], [2, 5, 4], [4, 5, 4], [5 , 5, 4], [2, 2, 5], [4, 2, 5], [5, 2, 5], [2, 4, 5], [4, 4, 5], [5, 4 , 5], [2, 5, 5], [4, 5, 5], [5, 5, 5]]

Затем суммируя это:

List<Integer> sum = integersList.stream()
        .map(a -> a.stream().reduce(Integer::sum).get())
        .sorted().collect(toList());

Конечный результат:

[6, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 11, 11, 11, 12, 12, 12 , 12, 13, 13, 13, 14, 14, 14, 15]

0 голосов
/ 02 апреля 2020

Это должно работать. Мы создаем поток всех массивов, затем отображаем сумму этих массивов как целые числа и находим максимальное значение.

        int max = Stream.of(arr1, arr2, arr3)
                .map(array -> IntStream.of(array).sum())
                .max(Integer::compareTo)
                .orElseThrow(IllegalStateException::new);
...