【问题标题】:Dividing ArrayList into smaller ArrayLists with specific amount of element将 ArrayList 划分为具有特定数量元素的较小 ArrayList
【发布时间】:2019-02-06 22:04:33
【问题描述】:

我不是程序员。我在仓库工作,我想让我的工作更轻松。我的职责之一是将超过 2000 行的 excel 文件分成较小的文件并发送出去。我手动完成,我想创建一个为我完成的程序。

我已经设法从 excel 中读取数据。每一行都放入一个 Item 数据结构中。并且全部放入ArrayList中。

public class Item{
    String ean;
    int amount;
}

这是我的问题。

我有一个包含 2000 多个元素的 ArrayList。每个元素都有 String Name 和 int amount。

我必须把它分成更小的ArrayLists,但条件是item.getAmount()的总量不能超过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++;
}

当我使用包含 30 个项目的 ArrayList 运行此程序时,每个项目的数量为 100。它会创建 4 个 excel 文件。前三个只有 1 行,第四个有 4 行。

我想不通。有什么建议吗??

【问题讨论】:

  • 你不应该清除temp之后你在createFile中使用它吗?您正在擦除列表,向其中添加元素,然后使用已擦除的列表创建文件。
  • 欺骗关闭不是我说你的问题不好,而是我说你的答案在另一座城堡里。无论如何,我想不出比其他答案更好的方法。
  • @Makoto 这不是同一个问题。这些答案中的大多数在这里都无关紧要。
  • @Makoto,要求似乎是每个子列表中Items 的amount 属性值的总和不超过800。这与子列表的大小无关。
  • 应该totalAmount = 0;totalAmount = item.getAmount();

标签: java arraylist


【解决方案1】:

关于生成长度为 8、9、9、4 的子列表的修改代码,问题是在将当前子列表刷新到文件后,您错误地重置了 totalAmount,而没有考虑到您所在的项目目前正在处理。您最终会得到 temp 包含一个元素,但 totalAmount 为零。

为了使 totalAmount 反映 temp 中项目的 amounts 的正确总和,该替代方案应该看起来更像这样:

    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
    }

【讨论】:

    【解决方案2】:

    我发现更容易不考虑将事物添加到列表中,然后将其清除,而只是通过识别不超过目标总和 (*) 的子列表的开始和结束:

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

    (*) 你可能会得到一个超过总和的单元素子列表,例如如果金额是801。你不能对这种情况做任何事情,除了自己写。

    【讨论】:

    • 这个有效,我非常感谢你和其他在这个线程中回答的人。这将使我的工作不那么烦人。如果我可以再问一个问题。如果我希望每个文件最多有 8 行怎么办?
    • 将while循环的条件改为end &lt; items.size() &amp;&amp; (end - start) &lt; 8
    猜你喜欢
    • 1970-01-01
    • 2016-07-22
    • 2013-12-13
    • 2012-03-28
    • 2011-10-06
    • 1970-01-01
    • 2015-06-07
    • 1970-01-01
    • 2017-01-24
    相关资源
    最近更新 更多