Stream Hash Map с использованием Lambda - PullRequest
0 голосов
/ 30 августа 2018

Пример SQL-результата

dataResult
Code    Amt      TotalAmtPerCode
A1      4           0
A1      4           0
B1      4           0
B1      5           0
A1      6           0

с этим результатом я хотел бы спросить о том, как вычислить TotalAmtPerCode Ожидаемый результат должен быть

Code    Amt      TotalAmtPerCode
A1      4           14
A1      4           14
B1      4           9
B1      5           9
A1      6           14

образец кода

for (Map<String, Object> data: dataResult) {
    Long total = ComputeTotalAmount(dataResult,data.get(DBColumn.Code.name();
    container.setTotalAmtPerCode(total);
}

функция, которая вычисляет общую сумму

private static long ComputeTotalAmount(List<Map<String, Object>> list, String code) {
    Long total = 0;
    for (Map<String, Object> data: dataResult) {
        if (code.equals(data.get(DBColumn.Code.name()))) {
            total = total+Long.valueOf(data.get(DBColumn.Code.name()).toString)
        }
    }        
}

Этот работает нормально, но я хотел бы попросить оптимизацию этого кода. Потому что, если бы я зациклил 10000 записей, он проверил бы 1-ю запись для кода, затем повторил бы 10 тыс., Чтобы найти тот же код и получить сумму по этому коду и суммировать все это, тогда он проверил бы 2-ю запись и т. Д.

Ответы [ 2 ]

0 голосов
/ 30 августа 2018

Добро пожаловать в StackOverflow:)

Насколько я понимаю, вам нужно сгруппировать сумму значений TotalAmtPerCode по Code. Существует метод Stream::collect для преобразования значений в требуемый вывод с использованием коллектора Collectors::groupingBy, который группирует Stream<T> в Map<K, V>, где V - это коллекция.

Map<String, Integer> map = dataresult.stream()
    .collect(Collectors.groupingBy(                                             // Group to Map
         d -> d.get(DBColumn.Code.name()),                                      // Key is the code
         Collectors.summingInt(d -> d.get(DBColumn.TotalAmtPerCode.name())))); // Value is the sum

Примечание:

  • Возможно, вам потребуется отредактировать d -> d.get(DBColumn.Code.name()) и d.get(DBColumn.TotalAmtPerCode.name()) в соответствии с вашими потребностями, чтобы получить Code и TotalAmtPerCode - я не знаю модель данных.

  • Я предполагаю, что TotalAmtPerCode равно int. В противном случае используйте Collectors.summingLong.

0 голосов
/ 30 августа 2018

Вы можете использовать Collectors.groupingBy () :

Map<String, Long> collect = list.stream()
    .collect(Collectors.groupingBy(
        p -> p.getFirst(),
        Collectors.summingLong(p -> p.getSecond())
    )
);

Это группирует ввод по некоторому классификатору (здесь это p -> p.getFirst(), это, вероятно, будет что-то вроде data.get(DBColumn.Code.name()) в вашем случае) и суммирует значения (p -> p.getSecond(), которые должны быть изменены на что-то вроде Long.valueOf(data.get(DBColumn.Code.name()).toString)) .

Примечание: getFirst() и getSecond() являются методами из org.springframework.data.util.Pair.

Пример:

List<Pair<String, Long>> list = new ArrayList<>();
list.add(Pair.of("A1", 1L));
list.add(Pair.of("A1", 2L));
list.add(Pair.of("B1", 1L));

Map<String, Long> collect = list.stream()
    .collect(Collectors.groupingBy(
        p -> p.getFirst(),
        Collectors.summingLong(p -> p.getSecond())
    )
);
System.out.println(collect);

Выход:

{A1=3, B1=1}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...