【问题标题】:Java 8 Looping Special Pyramid LogicJava 8 循环特殊金字塔逻辑
【发布时间】:2019-03-24 20:23:13
【问题描述】:

我有一个List<Integer> list=Arrays.asList(640,480,520,170,320,140,60); 我需要根据下面的迭代逻辑找到给定元素的总和。 例如第一个外部迭代,如 640+480,然后 640+480+520,依此类推,直到 60。

下一次迭代从 480+520 开始,然后是 480+520 +170 等等。

示例 Java 7 程序类似于

List<Integer> list=Arrays.asList(640,480,520,170,320,140,60);
        List<Integer> newListWithSum=new ArrayList<>();
        for(int mainIndex=0;mainIndex<list.size();mainIndex++) {
            for(int index=mainIndex;index<list.size();index++) {
                int sum=0;
                for(int nestedIndex=mainIndex;nestedIndex<index+1;nestedIndex++) {
                    sum=sum+list.get(nestedIndex);
                }
                newListWithSum.add(sum);
            }
        }

但我需要将上述逻辑更改为 Java 8 版本。请帮助/分享提示以根据以下迭代编写简化的 Java 8 逻辑求和

【问题讨论】:

  • 是的,Java 7 逻辑在上面列出。我需要将它迁移到 Java 8。
  • 你需要将它“迁移”到 java-8 吗?
  • 我的意思是为了更好的版本,我需要将它更改为 Java 8(如果 Stream/IntStream)是更好的选择吗?
  • 不,你所拥有的已经很不错了。在这种情况下,java-8 不会提高速度/可读性或其他任何东西

标签: java loops foreach java-8 java-stream


【解决方案1】:

感觉这个和算法比较像,我们一步一步来

1) 首先在每次迭代中排除第一个整数得到所有子列表

List<Integer> list=Arrays.asList(640,480,520,170,320,140,60);

    List<List<Integer>> re = IntStream.range(0, list.size())
                                      .mapToObj(sb->list.subList(sb, list.size()))
                                      .filter(s->s.size()>1)
                                      .collect(Collectors.toList());

    re.forEach(ls->System.out.println(ls));

输出

[640, 480, 520, 170, 320, 140, 60]
[480, 520, 170, 320, 140, 60]
[520, 170, 320, 140, 60]
[170, 320, 140, 60]
[320, 140, 60]
[140, 60]

2) 现在对每个列表进行求和

List<List<Integer>> re1 = re.stream()
                            .map(j->IntStream.rangeClosed(2, j.size()).mapToObj(sl->j.stream().limit(sl).mapToInt(Integer::intValue).sum()).collect(Collectors.toList()))
                            .collect(Collectors.toList());

 re1.forEach(ls->System.out.println(ls));

输出

[1120, 1640, 1810, 2130, 2270, 2330]
[1000, 1170, 1490, 1630, 1690]
[690, 1010, 1150, 1210]
[490, 630, 690]
[460, 520]
[200]

第1步和第2步的组合解决方案

List<List<Integer>> re = IntStream.range(0, list.size())
                                      .mapToObj(sb->list.subList(sb, list.size()))
                                      .filter(s->s.size()>1)
                                      .map(j->IntStream.rangeClosed(2, j.size()).mapToObj(sl->j.stream().limit(sl).mapToInt(Integer::intValue).sum()).collect(Collectors.toList()))
                                      .collect(Collectors.toList());

【讨论】:

    【解决方案2】:

    如果你只是想转换你拥有的代码,你可以使用下面的 sn-p:

    List<Integer> result = IntStream.range(0, list.size())
            .mapToObj(i -> list.subList(i,  list.size()))
            .flatMap(l -> IntStream.rangeClosed(1, l.size()).mapToObj(i -> l.subList(0, i).stream().reduce(0, Integer::sum)))
            .collect(Collectors.toList());
    

    这会创建一个从0n - 1Intstream,并映射应汇总项目的所有列表。这些列表再次映射到实际项目以计算总和。这是在reduce 步骤中启用的。最后,所有流都被展平并最终收集到结果列表中:

    [640, 1120, 1640, 1810, 2130, 2270, 2330, 480, 1000, 1170, 1490, 1630, 1690, 520, 690, 1010, 1150, 1210, 170, 490, 630, 690, 320, 460, 520, 140, 200, 60]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-09
      相关资源
      最近更新 更多