So I have a an array List that looks like this: <id,value,id,value,...>
and I should find all the elements with the same id and add together there respected values into a result array list (value always comes after the id). At first I thought the problem was easy and went ahead and tried this:
List<String> resultList = new ArrayList<>();
for(int i = 0; i < myList.size(); i+=2){
BigInteger currentID = new BigInteger(myList.get(i));
BigInteger currentSum = new BigInteger(myList.get(i+1));
String currentId = myList.get(i);
int j = 2;
while(j < myList.size()){
if(currentId.equals(myList.get(j))){
BigInteger value2 = new BigInteger(myList.get(j+1));
currentSum = currentID.add(value2);
}
resultList.add(currentId);
resultList.add(String.valueOf(currentSum));
j+=2;
}
}
Needless to say it isn't correct, one of the many problems is that values which haven been already added together will be readded into the result array so I think they should be removed somehow in the loop. Do you guys have any suggestions how to go around this?
If you want to use streams you can do it like this.
Given a list like the following:
List<BigInteger> list = List.of(1,10,3,20,3,40,1,5,4,7,1,8,4,9,6,20)
.stream().mapToLong(a -> a).mapToObj(
BigInteger::valueOf).collect(Collectors.toList());
First accumulate the sums in a map with the key
being the id.
Map<BigInteger, BigInteger> mapfinal =
IntStream.iterate(0, i -> i < list.size(), i -> i += 2).mapToObj(
i -> new BigInteger[] { list.get(i), list.get(i + 1)
}).collect(Collectors.groupingBy(i -> i[0],
Collectors.reducing(BigInteger.ZERO,
a -> a[1],
(a, b) -> a.add(b))));
You can stop there and just use the map, or you can convert it to a list like the one you started with of alternating id/value
pairs.
List<BigInteger> listfinal = mapfinal
.entrySet()
.stream()
.flatMap(e -> Stream.of(e.getKey(), e.getValue()))
.collect(Collectors.toList());
And print the list.
System.out.println(listfinal);
[1, 23, 3, 60, 4, 16, 6, 20]