Java:创建用于处理的列表块

Java : Creating chunks of List for processing

我有一个包含大量元素的列表。在处理这个列表时,在某些情况下我希望将列表划分为更小的子列表,而在某些情况下我想处理整个列表。

private void processList(List<X> entireList, int partitionSize)
{
    Iterator<X> entireListIterator = entireList.iterator();
    Iterator<List<X>> chunkOfEntireList =   Iterators.partition(entireListIterator, partitionSize);
    while (chunkOfEntireList.hasNext()) {
        doSomething(chunkOfEntireList.next());
        if (chunkOfEntireList.hasNext()) {
            doSomethingOnlyIfTheresMore();
        }
    }

我正在使用 com.google.common.collect.Iterators 创建分区。 Link 文档 here 因此,如果我想将列表分区为 100,我会调用

processList(entireList, 100);

现在,当我不想创建列表块时,我想我可以将 Integer.MAX_VALUE 作为 partitionSize 传递。

processList(entireList, Integer.MAX_VALUE);

但这会导致我的代码内存不足。有人可以帮我吗?我错过了什么?迭代器在内部做什么,我该如何克服这个问题?

编辑:我还要求里面的 "if" 子句只有在有更多列表要处理时才做某事。即我需要迭代器的 hasNext() 函数。

通常在分区时它会分配给定分区大小的新列表。所以很明显在这种情况下会出现这样的错误。当您只需要单个分区时,为什么不使用原始列表。可能的解决方案。

  1. 创建一个单独的重载方法,您不会在其中获取大小。
  2. 当您不需要任何分区时,将大小传递为 -1。在方法中检查值,如果-1则将原始列表放入chunkOfEntireList,.

您遇到内存不足错误,因为 Iterators.partition() 在内部填充了具有给定分区长度的数组。分配的数组始终是分区大小,因为在迭代完成之前不知道元素的实际数量。 (如果他们在内部使用 ArrayList,这个问题本可以避免;我想设计者认为数组在常见情况下会提供更好的性能。)

使用 Lists.partition() 将避免该问题,因为它委托给 List.subList(),这只是基础列表的 视图

private void processList(List<X> entireList, int partitionSize) {
    for (List<X> chunk : Lists.partition(entireList, partitionSize)) {
        doSomething(chunk);
    }
}