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.