Reputation: 23
I am not a programmer. I work at warehouse and I would like to make my work easier. One of my responsibilities is to divide excel file with over 2000 rows into smaller ones and send them out. I do it manually and I would like to create a program that does it for me.
I have managed to read the data from excel. Each row is put into an Item data structure. And all of them are put into ArrayList.
public class Item{
String ean;
int amount;
}
Here is my problem.
I have one ArrayList with over 2000 elements. Each element has String Name and int amount.
I must divide it into smaller ArrayLists but the condition is that the total amount of item.getAmount() can´t be more than 800;
int totalAmount = 0;
int counter = 1;
List<Item> temp = new ArrayList<>();
for (Itema item: items) {
totalAmount += item.getAmount();
if (totalAmount <= 800) {
temp.add(item);
}
if (counter == items.size()) {
createFile(temp);
temp.clear();
}
if (totalAmount > 800) {
createFile(temp);
temp.clear();
temp.add(item);
totalAmount = 0;
}
counter++;
}
When I run this with ArrayList that contains thirty items each with amount 100. It creates 4 excel files. First three only have 1 row each and fourth one has 4 rows.
I can't figure it out. Any suggestions??
Upvotes: 2
Views: 125
Reputation: 140309
I find it easier not to think of it in terms of adding things into a list, and then clearing it afterwards, but rather just by identifying the start and end of sublists which don't exceed the target sum (*):
int start = 0;
while (start < items.size()) {
// Move the end pointer until your total exceeds 800.
int end = start + 1;
int totalAmount = items.get(start).getAmount();
while (end < items.size()) {
int amount = items.get(end).getAmount();
if (totalAmount + amount > 800) {
break;
}
totalAmount += amount;
end++;
}
// Now flush the sublist between start and end:
createFile(items.subList(start, end));
// Now move on to the next.
start = end;
}
(*) You may get a single-element sublist which exceeds the sum, e.g. if the amount is 801. You can't do anything with that case, other than write it by itself.
Upvotes: 3
Reputation: 180103
With respect to the revised code producing sublists of length 8, 9, 9, 4, the problem is that after flushing the current sublist to a file, you reset the totalAmount
incorrectly, not taking into account the item you are currently processing. You end up with temp
containing one element, but totalAmount
being zero.
To make totalAmount
reflect the correct sum of the amount
s of the items in temp, that alternative should look more like this:
if (totalAmount > 800) {
createFile(temp);
temp.clear();
temp.add(item); // temp now contains one element
totalAmount = item.getAmount(); // this is the 'amount' of that element
}
Upvotes: 1