Java Stream将整数列表分为3部分,每部分的总和

时间:2018-07-11 11:10:44

标签: java java-8

我需要将Integer列表分为相等部分并打印每个数组的总和

ex [4,2,3,4,1,1,1,2,1]

分为[4,2,3],[4,1.1],[1,2,1]和每个最终结果的总和964

需要使用Java 8流api

AtomicInteger counter = new AtomicInteger(0);

Integer[] array = {4, 2, 3, 4, 1, 1, 1, 2, 1};


Arrays.asList(array).stream().collect(Collectors.groupingBy(it -> counter .getAndIncrement() / 3)).forEach((k,v)->System.out.println(k + " " + v));

它打印

{0=[4, 2, 3], 1=[4, 1, 1], 2=[1, 2, 1]}

我需要打印每个部分的总和 964

谢谢

2 个答案:

答案 0 :(得分:4)

请勿使用外部计数器。由于流无法保证特定的处理顺序,因此无法保证计数器更新会真正反映实际的元素位置。

简单的解决方案并不那么复杂:

int[] array = {4, 2, 3, 4, 1, 1, 1, 2, 1};
int chunks = 3, chunkSize = array.length/chunks;
IntStream.range(0, chunks).forEach(i -> System.out.println(i+" "
    +Arrays.stream(array, i*=chunkSize, i+chunkSize).sum()));

如果数组长度不能被三整除,它将忽略多余的元素。

如果数组确实是Integer[]而不是int[],则必须将元素拆箱:

Integer[] array = {4, 2, 3, 4, 1, 1, 1, 2, 1};
int chunks = 3, chunkSize = array.length/chunks;
IntStream.range(0, chunks).forEach(i -> System.out.println(i+" "
    +Arrays.stream(array, i*=chunkSize, i+chunkSize)
           .mapToInt(Integer::intValue)
           .sum()));

上述解决方案适用于“将整数列表分为3部分”,与您的问题的标题相匹配。如果您想拆分成长度为三的部分,只需将解决方案更改为

int chunkSize = 3;
IntStream.range(0, array.length/chunkSize).forEach(i -> System.out.println(i+" "
    +Arrays.stream(array, i*=chunkSize, i+chunkSize)
           .mapToInt(Integer::intValue)
           .sum()));

如果要通过处理最后一个可能较短的块来处理chunkSize无法整除的数组长度,可以使用

Integer[] array = {4, 2, 3, 4, 1, 1, 1, 2, 1, 100};
int chunkSize = 3;
IntStream.range(0, (array.length+chunkSize-1)/chunkSize)
    .forEach(i -> System.out.println(i+" "
        +Arrays.stream(array, i*=chunkSize, Math.min(i+chunkSize, array.length))
               .mapToInt(Integer::intValue)
               .sum()));

答案 1 :(得分:1)

您在遇到Map<Integer, List<Integer>>时就停止了问题:{0=[4, 2, 3], 1=[4, 1, 1], 2=[1, 2, 1]}

您需要

  • 反复讨论Lists
  • 求和元素
  • 打印它们(或收集它们以构建int
Arrays.asList(array).stream()
    .collect(Collectors.groupingBy(it -> counter .getAndIncrement() / 3))
    .values()
    .stream()
    .mapToInt(val-> val.stream().mapToInt(Integer::intValue).sum())
    .forEach(System.out::print);

Workable Demo : print

要获取其中的String

String res = Arrays.asList(array).stream()
        .collect(Collectors.groupingBy(it -> counter .getAndIncrement() / 3))
        .values().stream()
        .map(val-> val.stream().mapToInt(Integer::intValue).sum())
        .map(String::valueOf)
        .collect(Collectors.joining());
        System.out.println(res);

Workable Demo : collect as String


更简短但更不易理解的方法可以是:

  • ints进行迭代,在您的情况下以3隔开:0、3、6、9 ...
  • 将每个映射到从indexindex+3的数组值之和
IntStream.iterate(0,i->i+size)
    .limit(array.length/size)
    .map(i -> Arrays.stream(array).skip(i).limit(size).mapToInt(Integer::intValue).sum())
    .forEach(System.out::print);