How to Get Summation of Pair(Key) Values in a Map in Java

how to get summation of pair(key) values in a map in java?

You can create a function as such:

int getSummationOfValuesByKey(Map<Pair<String,Integer>, Integer> map, String key) {
return map.entrySet()
.stream()
.filter(e -> e.getKey().getKey().equals(key))
.mapToInt(Map.Entry::getValue)
.sum();
}

which given a map and a key will return the summation of the values where the Pair's key is equal to the provided key.

Sum of values in the map for specific key

When you want to write functional code, the rule is: don't use forEach. This is an imperative solution and breaks functional code.

What you want is to split each line and group by the first part (key) while summing the second part (values):

Map<String, Integer> map = 
Files.lines(Paths.get("/Users/walter/Desktop/stuff.txt"))
.map(s -> s.split("\\s+"))
.collect(groupingBy(a -> a[0], summingInt(a -> Integer.parseInt(a[1]))));

In this code, we are splitting each line. Then, we are grouping the Stream using Collectors.groupingBy(classifier, downstream) where:

  • classifier, which is a function that classifies each item to extract the key of the resulting Map, just returns the first part of the line
  • downstream is a collector that reduces each value having the same key: in this case, it is Collectors.summingInt(mapper) which sums each integer extracted by the given mapper.

As a side-note (and just so you know), you could rewrite your whole forEach more simply using the new Map.merge(key, value, remappingFunction) method, with just a call to:

map.merge(line[0], Integer.valueOf(line[1]), Integer::sum);

This will put a new value with the key line[0] with the value Integer.valueOf(line[1]) if this key did not exist, otherwise, it will update the key with the given remapping function (which is the sum of the old and new value in this case).

Finding the sum of each ListMultiMap Key

There's no built-in function to do so, but treating the multimap as a Map (with asMap()) will give you a collection of the values per day. From there, you just need to sum them, e.g., by streaming them and converting them to primitives:

int p = 0;
for (Collection<Long> vals : foodCals.asMap().values()) {
System.out.println(p + " - " + vals.stream().mapToLong(Long::longValue).sum());
p++;
}

EDIT:

For older Java versions (before 8), the same logic should apply, although the syntax is a bit clunkier, and you'll have to sum the values yourself:

int p = 0;
for (Collection<Long> vals : foodCals.asMap().values()) {
long sum = 0L;
for (Long val : vals) {
sum += val;
}
System.out.println(p + " - " + sum);
p++;
}

Sum of values from hashmap using streams

You seem to be looking for something like :

BigInteger sumOfValues = hashMap.entrySet().stream()
.filter(e -> e.getKey().compareTo(min) > 0 && e.getKey().compareTo(max) < 0)
.map((Map.Entry::getValue))
.reduce(BigInteger.ZERO, BigInteger::add);

or stated as in your code

Long sumOfValues = hashMap.entrySet().stream()
.filter(e -> e.getKey().compareTo(min) > 0 && e.getKey().compareTo(max) < 0)
.map((Map.Entry::getValue))
.reduce(BigInteger.ZERO, BigInteger::add).longValue();

Filter on inner map key and value pair in order to sum on an attribute value

groupedTotals
.entrySet().stream()
.filter(e -> e.getKey().date().equals(date)) // same so far
.map(Entry::getValue) // get out the Map<StudentType, List<Score>>
.map(m -> m.get(StudentType.ACTIVE)) // get the List<Score>
.filter(Objects::nonNull) // remove nulls from maps without ACTIVE
.flatMap(List::stream) // get just a Stream<Score>
.filter(Score::isValid) // filter the valid scores
.mapToDouble(Score::grade) // map directly to double
.sum() // sum results

how to sum hashmap values with same key java

First, please program to the interface (not the concrete collection type). Second, please don't use raw types. Next, your Map only needs to contain the name of the pet and the sum of the prices (so String, Double). Something like,

public void calc(List<Pet> pets) {
Map<String, Double> hm = new HashMap<>();
for (Pet i : pets) {
String name = i.getShop();
// If the map already has the pet use the current value, otherwise 0.
double price = hm.containsKey(name) ? hm.get(name) : 0;
price += i.getPrice();
hm.put(name, price);
}
System.out.println("");
for (String key : hm.keySet()) {
System.out.printf("%s: %.2f%n", key, hm.get(key));
}
}

is there a way to get values of a map of pair and value by the key pair only?

You can create a method as such:

int[] getValuesByKey(Map<Pair<String,Integer>, Integer> map, String key) {
return map.entrySet()
.stream()
.filter(e -> e.getKey().getKey().equals(key))
.mapToInt(Map.Entry::getValue)
.toArray();
}

which given a map and a key will yield all the values where the entry key is equal to the provided key.

or if you want an Integer array then you can do:

Integer[] getValuesByKey(Map<Pair<String,Integer>, Integer> map, String key) {
return map.entrySet()
.stream()
.filter(e -> e.getKey().getKey().equals(key))
.map(Map.Entry::getValue)
.toArray(Integer[]::new);
}

or if you want to retrieve a list.

List<Integer> getValuesByKey(Map<Pair<String,Integer>, Integer> map, String key) {
return map.entrySet()
.stream()
.filter(e -> e.getKey().getKey().equals(key))
.map(Map.Entry::getValue)
.collect(Collectors.toCollection(ArrayList::new));
}

How to sum values from Java Hashmap

If you need to add all the values in a Map, try this:

float sum = 0.0f;
for (float f : map.values()) {
sum += f;
}

At the end, the sum variable will contain the answer. So yes, for traversing a Map's values it's best to use a for loop.

Merge two maps with same keys in java and add the value together

Either the values in col map should be of numeric type to allow for arithmetic operations, or another map Map<String, Integer> should be created to store the results of calculations.

Also, there's no need to have a nested loop to calculate the sums while reading the data because the calculation results will be incorrect.

There are several ways to accumulate the sums in the map per key.

  1. Use method Map::compute
Map<String, Integer> col = new HashMap<>(); // changed value type to Integer
// ...
Integer number = 0;
while (cmd.hasNextLine()) {
String line = cmd.nextLine();
if (line.charAt(9) == 'A') {
number = Integer.valueOf(line.substring(23, 28));
Name = line.substring(29, 34);
col.compute(Name, (key, prev) -> (prev == null ? 0 : prev) + number);
}
// no need for nested loop
}

// print map contents
col.forEach((name, sum) -> System.out.print("%s %04d%n", name, sum));

  1. Use method Map::merge along with Integer::sum which can be replaced with a lambda (sum, val)-> sum + val:
Integer number = 0;
while (cmd.hasNextLine()) {
String line = cmd.nextLine();
if (line.charAt(9) == 'A') {
number = Integer.valueOf(line.substring(23, 28));
Name = line.substring(29, 34);
col.merge(Name, number, Integer::sum);
}
}
// print map contents
col.forEach((name, sum) -> System.out.print("%s %04d%n", name, sum));


Related Topics



Leave a reply



Submit