Java 8 Looping Специальная логика пирамиды - PullRequest
1 голос
/ 24 марта 2019

у меня есть 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 на сумму согласно итерации ниже

enter image description here

Ответы [ 2 ]

1 голос
/ 25 марта 2019

Мне кажется, это намного больше похоже на алгоритм, давайте пошагово шаг за шагом

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());
0 голосов
/ 25 марта 2019

Если вы просто хотите преобразовать свой код, вы можете использовать следующий фрагмент:

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());

Это создает Intstream от 0 до n - 1 и отображает все списки, которые элементы должны быть суммированы. Эти списки снова сопоставляются с фактическими позициями для расчета суммы. Это включено в шаге 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]
...