Java Streams Sum Values of a List of Maps

Java streams sum values of a List of Maps

Here is the simple solution, it will give the result as per your requirement:

List<Map<String, Long>> mapList = new ArrayList();
Map<String, Long> map1 = new HashMap<>();
Map<String, Long> map2 = new HashMap<>();
Map<String, Long> map3 = new HashMap<>();
map1.put("col1", 90L);
map1.put("col2", 50L);
map1.put("col3", 10L);
map2.put("col1", 90L);
map2.put("col2", 50L);
map2.put("col3", 10L);
map3.put("col1", 90L);
map3.put("col2", 50L);
map3.put("col3", 10L);
mapList.add(map1);
mapList.add(map2);
mapList.add(map3);

Map<String, Long> sum = new HashMap<>();
mapList.forEach(map -> map.keySet().forEach(
s -> {
mapList.stream()
.collect(Collectors.groupingBy(foo -> s,
Collectors.summingLong(foo -> map.get(s)))).forEach(
(id, sumTargetCost) ->
sum.put(s, sumTargetCost)
);
}

));

Long sumVal1 = sum.get("col1"); // 270
Long sumVal2 = sum.get("col2"); // 150
Long sumVal3 = sum.get("col3"); // 30

System.out.println("SumVal1: " + sumVal1 + ", SumVal2: " + sumVal2 + ", SumVal3: " + sumVal3);

How to compute sum for each list in Map<>?

You could try this

Map<LocalDate,Integer> result = new LinkedHashMap<>();
map.forEach((key, value) -> {
result.put(key,value.stream().mapToInt(Integer::intValue).sum());
});

Get the sum of values from a HashMap where the keys have matches in a List of Strings with streams

Stream over the list (second), rather than the map. Map each element of the list by querying the map. If an element is not in the map, the result will be null, so we remove those elements with a filter. Finally, we can do a sum:

long third = second.stream()
.map(first::get)
.filter(Objects::nonNull)
.mapToLong(x -> x)
.sum();

Java 8 stream - sum list of numbers for every map key

To change from Map<String, List<BigDecimal>> to Map<String, BigDecimal> there are two steps :

First step : use Collectors.toMap to take the keys of the old map to the new map.

Second step : you have to sum all the elements of your List<BigDecimal> there are many ways one of them is to use e.getValue().stream().reduce(BigDecimal.ZERO, BigDecimal::add)

In the end your code can look like this :

Map<String, BigDecimal> result = map.entrySet().stream()
.collect(Collectors.toMap(
Map.Entry::getKey,
e -> e.getValue().stream().reduce(BigDecimal.ZERO, BigDecimal::add))
);

Ideone example

Java 8 stream Map<String, List<String>> sum of values for each key

You could also use the forEach method along with the stream API to yield the result you're seeking.

Map<String, Double> resultSet = new HashMap<>();
inputMap.forEach((k, v) -> resultSet.put(k, v.stream()
.mapToDouble(s -> computeScore(s)).sum()));

s -> computeScore(s) could be changed to use a method reference i.e. T::computeScore where T is the name of the class containing computeScore.

How to sum values in a Map with a stream?

Here's another way to do this:

int sum = data.values().stream().reduce(0, Integer::sum);

(For a sum to just int, however, Paul's answer does less boxing and unboxing.)

As for doing this generically, I don't think there's a way that's much more convenient.

We could do something like this:

static <T> T sum(Map<?, T> m, BinaryOperator<T> summer) {
return m.values().stream().reduce(summer).get();
}

int sum = MyMath.sum(data, Integer::sum);

But you always end up passing the summer. reduce is also problematic because it returns Optional. The above sum method throws an exception for an empty map, but an empty sum should be 0. Of course, we could pass the 0 too:

static <T> T sum(Map<?, T> m, T identity, BinaryOperator<T> summer) {
return m.values().stream().reduce(identity, summer);
}

int sum = MyMath.sum(data, 0, Integer::sum);

Map of List: Sum all the values of the list class

If you need a sum of all the passengers for all cars in the map that will do the job:

            map.values()
.stream()
.flatMap(List::stream) // Stream of car objects
.mapToInt(Car::getPassengers)
.sum();

Example for filtering colors:

           map.entrySet()
.stream()
.filter(entry -> entry.getKey() == Colour.RED ||
entry.getKey() == Colour.BLACK) // only entries for BLACK and RED will remain
.map(Map.Entry::getValue) // Stream<List<Car>>
.flatMap(List::stream) // Stream<Car>
.mapToInt(Car::getPassengers)
.sum();

Side note:

  • instead of HashMap for a Map with enum-keys use EnumMap, this special-purpose implementation is designed to be used only with enums and has better performance.

Sum values from Maps using streams and collect to List

You can do this:

List<Integer> result = myList.stream()
.map(list -> list.stream()
.flatMapToInt(map -> map.values()
.stream()
.mapToInt(i -> (int) i))
.sum())
.collect(Collectors.toList());

A list of maps group by and sum up with a certain key

This is similar to your previous question

Collection<Tag> tagGroupedList  = tagGrouped.values().stream().flatMap(tags -> tags.stream()).collect(Collectors.toMap(tag -> tag.getCategory(), Function.identity(), (tag1, tag2) -> {
tag1.setPrice(tag1.getPrice() + tag2.getPrice());
return tag1;
})).values();
//tagGroupedList will have the data what you need


Related Topics



Leave a reply



Submit