У меня есть LinkedHashMap, где у меня есть два повторяющихся ключа с соответствующими значениями, мне нужно знать, как СУММИРОВАТЬ эти значения в один ключ. В настоящее время он удаляет старое дублированное значение и ставит новое.
Это моя карта
static Map<String, Double> costByDuration = new LinkedHashMap<>();
Здесь я помещаю значения (call_from может быть 912345678 и иметь значение 10, а затем еще один вызов из 912345678 и иметь значение 20), затем я хочу, чтобы 912345678 имел значение 30 вместо сохранения только одного.
costByDuration.put(call_from, toPay);




Используйте функцию слияние:
costByDuration.merge(call_from, toPay, (oldPay, toPay) -> oldPay + toPay);
oldPay - это существующее значение, карта вычислит его автоматически. см. отредактированный ответ
Сначала вам нужно будет проверить, есть ли ваше значение уже на карте.
Double existingValue = costByDuration.get(callFrom);
if (existingValue != null) {
costByDuration.put(callFrom, existingValue + toPay);
} else {
costByDuration.put(callFrom, toPay);
}
Кстати, использовать Double для хранения суммы денег - плохая идея, если вы хотите, чтобы ваши арифметические операции давали вам правильный ответ. Я настоятельно рекомендую использовать BigDecimal вместо Double.
можно упростить с помощью Map::merge, но мне нравится +1 :)
Я бы создал следующий метод:
public void put(String key, Double value){
costByDuration.merge(key,value , Double::sum);
}
тогда вариант использования будет следующим:
put(call_from, toPay);
put(anotherKey, anotherValue);
...
...
Это решение внутренне использует метод merge, который в основном говорит, что если указанный ключ еще не связан со значением или связан с нулем, связывает его с заданным ненулевым значением. В противном случае заменяет связанное значение результатами заданной функции переназначения.
Хороший. И что интересно, у Double есть функциональная версия + (о которой я до сих пор не знал), но не -, *, / или %.
@DawoodibnKareem, я предполагаю, что это дополнение является наиболее часто используемым, но, опять же, можно утверждать, что ему не хватает последовательности. Думаю, только авторы могут ответить ...
Я бы, наверное, не стал называть метод put, потому что put, который сливается, а не заменяет, удивит будущих читателей. Возможно, addToTotal или любое другое имя подходит для вашего домена
@Hulk Хороший крик, спасибо !. Я не особо задумывался об именовании, когда публиковал ответ. Думаю, мы оставим это OP после того, как выберем лучшее имя, которое соответствует модели домена, как вы упомянули. :)
Попробуйте это с помощью метода containsKey:
static Map<String, Double> costByDuration = new LinkedHashMap<>();
if (costByDuration.containsKey(call_from) {
costByDuration.put(call_from, map.get(call_from) + to_Pay);
} else {
costByDuration.put(call_from, to_Pay);
}
что для вас oldPay?