You can achieve this with only myList.size()/3
iterations. Use an IntStream
to iterate with custom increments (we use 3 which is the window size):
IntStream.iterate(0, n -> n + 3).limit(myList.size() / 3)
Then collect the entries in a map:
Collectors.toMap(i -> myList.subList(i, i + 3), i -> (myList.get(i).getAmount()
+ myList.get(i + 1).getAmount() + myList.get(i + 2).getAmount()))
Let's assume I've added an extra item to myList
:
myList.add(new SaleTxn(7, "2018-10-16", 300));
Now myList.size()
equals to 7 and the solution only works if the size is 3, 6, or 9,... (myList.size() % 3 == 0
)
To cover the items left we need to check if there is items remaining:
if (myList.size() % 3 != 0) {
List<SaleTxn> remainderList = new ArrayList<>();
int remainderSum = 0;
for (int j = myList.size() % 3; j > 0; j--) {
remainderSum += myList.get(myList.size() - j).getAmount();
remainderList.add(myList.get(myList.size() - j));
}
result.put(remainderList, remainderSum);
}
Full code:
Map<List<SaleTxn>, Integer> result = IntStream.iterate(0, n -> n + 3).limit(myList.size() / 3).boxed()
.collect(Collectors.toMap(i -> myList.subList(i, i + 3), i -> (myList.get(i).getAmount()
+ myList.get(i + 1).getAmount() + myList.get(i + 2).getAmount())));
if (myList.size() % 3 != 0) {
List<SaleTxn> remainderList = new ArrayList<>();
int remainderSum = 0;
for (int j = myList.size() % 3; j > 0; j--) {
remainderSum += myList.get(myList.size() - j).getAmount();
remainderList.add(myList.get(myList.size() - j));
}
result.put(remainderList, remainderSum);
}
result.entrySet().forEach(e -> System.out.println(e));
Output:
[SaleTxn [id=4, txnDate=2018-10-13, amount=100], SaleTxn [id=5, txnDate=2018-10-14, amount=200], SaleTxn [id=6, txnDate=2018-10-15, amount=200]]=500
[SaleTxn [id=1, txnDate=2018-10-10, amount=100], SaleTxn [id=2, txnDate=2018-10-11, amount=200], SaleTxn [id=3, txnDate=2018-10-12, amount=100]]=400
[SaleTxn [id=7, txnDate=2018-10-16, amount=300]]=300
I added a toString()
method to SaleTxn
class to get the output above:
@Override
public String toString() {
return "SaleTxn [id=" + id + ", txnDate=" + txnDate + ", amount=" + amount + "]";
}