数组元素的总和

Ad *_*tum 9 java arrays java-stream

我对以下场景有疑问;

我有一个n-number数组ArrayList.数组的数量不是预先确定的,而数组的大小是固定的,但它可以包含空元素,空值被认为是零.我需要将每个单元格的总和放入新数组中的相应索引中,其大小在逻辑上与其他数组相同.

我试图将场景描述如下;

在此输入图像描述

我有一个经典的迭代方法的解决方案,但我最终得到了一个非常脏的实现.我很乐意看到你解决这个问题(最好是Stream api)

And*_*ner 28

非流解决方案(因为我不认为在流中可以使用易于理解的解决方案):

int[] result = new int[n];  // n is the length of each array.
for (Integer[] array : arrays) {
  for (int i = 0; i < n; ++i) {
    // Increment the i-th element of the result by the i-th element of array.
    // Use 0 in place of null.
    result[i] += array[i] != null ? array[i].intValue() : 0;
    // or (suggested by shmosel)
    // if (array[i] != null) result[i] += array[i];
  }
}
Run Code Online (Sandbox Code Playgroud)


Fed*_*ner 14

这是一种方法,灵感来自shmosel的答案:

Integer[] result = new Integer[FIXED_SIZE];
Arrays.setAll(result, i -> list.stream().mapToInt(a -> a[i] == null ? 0 : a[i]).sum());
Run Code Online (Sandbox Code Playgroud)

另一种方式是使用自定义收集器:

static <T> Collector<T[], ?, T[]> reducingByColumn(
        T identity,
        BinaryOperator<T> operator,
        IntFunction<T[]> factory) {

    return Collector.of(
        HashMap<Integer, T>::new,
        (map, a) -> IntStream.range(0, a.length)
            .forEach(i -> map.merge(i, a[i] == null ? identity : a[i], operator)),
        (m1, m2) -> {
            m2.forEach((k, v) -> m1.merge(k, v, operator));
            return m1;
        },
        map -> map.values().toArray(factory.apply(map.size())));
}
Run Code Online (Sandbox Code Playgroud)

此收集器使用映射来累积中间结果.

您可以按如下方式使用它:

Integer[] result = list.stream()
    .collect(reducingByColumn(0, Integer::sum, Integer[]::new));
Run Code Online (Sandbox Code Playgroud)


shm*_*sel 13

这是使用流的解决方案:

final int SIZE = ...
List<Integer[]> arrays = ...
Integer[] result = IntStream.range(0, SIZE)
        .map(i -> arrays.stream()
                .map(arr -> arr[i])
                .filter(Objects::nonNull)
                .mapToInt(Integer::intValue)
                .sum())
        .boxed()
        .toArray(Integer[]::new);
Run Code Online (Sandbox Code Playgroud)

  • 我只想说:这个解决方案很紧凑,但我不相信它是可读的.当然,如果我在我正在阅读的代码中找到它,我必须花一些时间来思考这个问题. (5认同)
  • `IntStream.of(0,SIZE)`只会给你第一个和最后一个元素,并且会给你一个超出范围的索引异常. (2认同)