2

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??

13
  • 1
    Shouldn't you be clearing temp after you've used it in createFile? You're erasing the list, adding an element to it, then using the erased list to create a file. Commented Aug 31, 2018 at 21:33
  • The dupe closure isn't me saying your question is bad, it's me saying that your answer is in another castle. I can't think of a better approach anyway than what's in that other answer. Commented Aug 31, 2018 at 21:37
  • @Makoto It's not the same question. Most of those answers are irrelevant here. Commented Aug 31, 2018 at 21:38
  • 2
    @Makoto, the requirement appears to be that the sum of the values of the amount properties of the Items in each sublist not exceed 800. It's not about the sizes of the sublists. Commented Aug 31, 2018 at 21:45
  • 1
    Should totalAmount = 0; be totalAmount = item.getAmount();? Commented Aug 31, 2018 at 21:47

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

2 Comments

This one works, I am very thankful to you and everyone else who answered in this thread. It is going to make my work much less annoying. If I may ask one more question. What if I want each file to have maximum of 8 rows?
Change the condition on the while loop to end < items.size() && (end - start) < 8.
1

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 amounts 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
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.