группировка и суммирование с вложенными списками - PullRequest
5 голосов
/ 25 марта 2019

У меня есть вложенные списки, и я пытаюсь сгруппировать и суммировать, чтобы получить желаемый результат, используя потоки Java и сборщики.При этом я не могу перебрать несколько SubAccounts.Либо я должен использовать для цикла или какой-то другой логики.Я хочу добиться с помощью потоков API.Есть ли возможность для этого

Map<Long, BigDecimal> assetQuanMap = subAccounts.getAssets.parallelStream().collect(Collectors.groupingBy(Asset::getAssetId, Collectors.reducing(BigDecimal.ZERO, Asset::getQuantity, BigDecimal::add)));

У меня есть следующие классы или представления:

    Account
        SubAccount1
            Assets
                1 - 20
                2 - 30
                3 - 40
        SubAccount2
            Assets
                1 - 10
                2 - 5
                3 - 3
        SubAccount3

                1 - 3
                2 - 3
                3 - 4

Класс счетов выглядит так:

Public class Account{
  List<SubAccounts> list;
}

Public Class SubAccounts    {
   List<Assets> list;
}

Public class Assets{
    Long assetId;
    BigDecimal quantity ;
}

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

1 - 33
2 - 38
3 - 47

1 Ответ

6 голосов
/ 25 марта 2019

Вы должны использовать два flatMap, чтобы вы могли группировать по assetId

Map<String, BigDecimal> collect = accounts.stream()
        .flatMap(account -> account.getList().stream())
        .flatMap(subAccount -> subAccount.getList().stream())
        .collect(Collectors.groupingBy(Assets::getAssetId,
                Collectors.reducing(
                        BigDecimal.ZERO, 
                        Assets::getQuantity,
                        BigDecimal::add)
        ));

из вашего кода assetId - это строка, поэтому ключ карты должен бытьСтрока, или вы должны конвертировать ее или изменить в своем классе, например:

Map<Long, BigDecimal> collect = accounts.stream()
        .flatMap(account -> account.getList().stream())
        .flatMap(subAccount -> subAccount.getList().stream())
        .collect(Collectors.groupingBy(asset -> Long.valueOf(asset.getAssetId()),
                Collectors.reducing(
                        BigDecimal.ZERO,
                        Assets::getQuantity,
                        BigDecimal::add
                )
        ));

Примечания

  • не делайтене используйте множественное число в имени классов;
  • не называйте переменную как list, используйте другое значимое имя;
  • не используйте assetId в качестве имени атрибута, вместо этого используйтепросто используйте id;
  • не используйте List в имени переменных assetList, вместо этого используйте s в конце, например assets или accounts.
...