简体   繁体   中英

Iterate through HashMap and sum key values that match same key

I have a set of values in a text file which I'm reading from. How can I store those values in a HashMap or List and compare them to later sum them? Ex:

"UniqueKey1" "Tom" 1
"UniqueKey2" "Tom" 2
"UniqueKey3" "Alex" 4

So since I have two Tom, I'd like to sum their values, which is 3

This is what I've tried:

Double counter = 0.0;
Map<String, Double> dataMap = new HashMap<String, Double>();
Iterator iterator = dataMap.entrySet().iterator();
List<String> matchingKeys = new ArrayList<>();
String dataFile = propertiesGetterUtilObj.getNewFilePath();
Path path = Paths.get(dataFile);

if(path != null) { 
    BufferedReader reader = Files.newBufferedReader(path);
    String lineValue = null;
          while ((lineValue = reader.readLine()) != null) {                                     
                String tradeId = token[0];
                String date = token[1];
                Double price = Double.parseDouble(token[2]);
                dataMap.put(date, price);

                }

Here I'm trying to map the date to be the key and what I want to sum which is the prices

how do I get those values added to the map and sum those who have the same key values and store it?

The point is that I will have unique values and repeated dates, then I would sum the values of those dates

Thank you

You cannot meaningfully "Iterate through [a] HashMap and sum key values that match [the] same key" because a Map cannot contain multiple mappings for the same key. You can, however, maintain a running sum of the values for each key as you add mappings.

There are multiple ways to do this, but one of the easier ones is to use HashMap.merge() to handle both adding new mappings and updating existing ones, as appropriate:

Map<String, Integer> myMap = new HashMap<>();

// ...
String key = "Tom";
int value = 4;

myMap.merge(key, value, (v1, v2) -> { return v1 + v2; });

Long approach compared to other answers. You could create an object. Then create a list of those objects and use a stream to map and sum their values.

Main

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 *
 * @author blj0011
 */
public class JavaApplication24 {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        List<PersonValueObject> data = new ArrayList();
        data.add(new PersonValueObject("Tom", 1));
        data.add(new PersonValueObject("Tom", 2));
        data.add(new PersonValueObject("Alex", 4));

        Map<String, Integer> result = data.stream().collect(Collectors.groupingBy(PersonValueObject::getName, Collectors.summingInt(PersonValueObject::getValue)));

        for (Map.Entry<String,Integer> entry : result.entrySet())  
            System.out.println("Key = " + entry.getKey() + 
                             ", Value = " + entry.getValue()); 
    }         
}

Object

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package javaapplication24;

/**
 *
 * @author blj0011
 */
public class PersonValueObject {
    private String name;
    private int value;

    public PersonValueObject(String name, int value) {
        this.name = name;
        this.value = value;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }


}

Output

run:
Key = Alex, Value = 4
Key = Tom, Value = 3
BUILD SUCCESSFUL (total time: 0 seconds)

You could create a class to map multiple key values if John's answer isn't what you are interested in. It would look something like this:

public class MultiMap<T> {
Map<Object, ArrayList<T>> multiMap = new HashMap<Object, ArrayList<T>>();

public void store(Object key, T value){
   if(!multiMap.containsKey(key)){
      multiMap.put(key, new ArrayList<T>());
   }
   multiMap.get(key).add(value);
   }

public ArrayList<T> get(Object key){
    return multiMap.get(key);
   }
}

Where you map multiple values per a key within a list that you can then iterate through.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM