简体   繁体   中英

Sum of List<Integer, Integer> elements in Java

I have an ArrayList which contain some Integer values as Pairs . I want to sum the right elements of the List where the left element is the same.

For example, the input arrayList will contain:

final List<Pair<Integer, Integer>> a = new ArrayList<>();
a.add(new Pair<>(1, 1));
a.add(new Pair<>(2, 1));
a.add(new Pair<>(2, 3));

New ArrayList should contain:

As seen below:

(common left value, sum of all the right values where left value is the same)

1, 1
2, 4

Code I have written that doesn't return valid values:

for (int i=0; i< a.size(); i++){


        //need help here
}

EDIT: I want duplicate pairs so a HashMap won't work.

Sorry for the edits.

Your problem is that you only add two elements in your loops which works for 1 but not for 2. Instead, you should use a map with the key being the first number (1 or 2 in your case) and the value being the sum.

Then you loop over both lists independently, get the current value for the left number, add the right number to it and put the result back into the map. If there's no value yet, you'd assume 0.

Something like this:

Map<Integer, Integer> sums = new HashMap<>();

for( Pair<> p : a ) {
  Integer sum = sums.get(p.left);
  if( sum == null ) {
    sums.put( p.left, p.right ); //nothing there yet, so just add the first value
  } else {
    sums.put( p.left, sum + p.right ); //add to the existing sum
  }
}

//do the same for b

Finally iterate over the map and build your new list of pairs as needed.

In case you need to get the original pairs as well, create a container object to be used as the value which contains the sum as well as a list of the pairs that contributed to that sum. I'll leave the code as an exercise for you.

This is untested code but should give you an idea

HashMap<Integer, Integer> result = new HashMap<Integer, Integer>();
List<Pair<Integer, Integer>> list = new ArrayList<Pair<Integer, Integer>>();

for (Pair p : a)
  if (result.containsValue(p.left)) 
    result.put(p.left, p.right +result.get(p.left)); // add if existing
  else
    result.put(p.left, p.right);                     // assign if not existing 

for (Pair p : b)
  if (result.containsValue(p.left)) 
    result.put(p.left, p.right +result.get(p.left));
  else
    result.put(p.left, p.right);   

ps (as per comment): add new pairs to list:

for (Pair p : a)
  list.add(new Pair(p.left, result.get(p.left)));

for (Pair p : b)
  list.add(new Pair(p.left, result.get(p.left)));

Using org.springframework.util.MultiValueMap:

List<Pair<Integer, Integer>> result = new ArrayList<>();

a.addAll(b); //now there is only one list

//key -> Integer, value -> List<Integer>
MultiValueMap<Integer, Integer> values = new LinkedMultiValueMap<Integer, Integer>();

for (Pair p : a) 
    values.add(p.left, p.right);

for (Integer key : values.keySet()) {
    Integer sum = 0;
    for (Integer right : values.get(key))
        sum += right;
    result.add(new Pair(key, sum));
}

It looks like you need some hacked HashMap , which will sum values instead of replacing them:

class SummingMap extends HashMap<Integer, Integer> {
    @Override
    public Integer put(Integer key, Integer value) {
        Integer oldResult = get(key);
        return super.put(key, value + (oldResult == null ? 0 : oldResult));
    }
}

If you want your entries to be sorted by key, you should use some kind of SortedMap , for example, TreeMap :

class SummingMap extends TreeMap<Integer, Integer> {
   ... // the same code as above

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