Java:创建List的块以进行处理

Abh*_*ahi 3 java performance list out-of-memory guava

我有一个包含大量元素的列表.处理此列表时,在某些情况下,我希望将列表分区为较小的子列表,在某些情况下,我希望处理整个列表.

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();
        }
    }
Run Code Online (Sandbox Code Playgroud)

我正在使用com.google.common.collect.Iterators来创建分区.这里的文档链接 因此,在我想要将大小为100的列表分区的情况下,我打电话给

processList(entireList, 100);
Run Code Online (Sandbox Code Playgroud)

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

processList(entireList, Integer.MAX_VALUE);
Run Code Online (Sandbox Code Playgroud)

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

编辑:我还要求内部的"if"子句只有在需要处理更多列表时才能执行某些操作.即我需要迭代器的hasNext()函数.

shm*_*sel 6

您将收到内存不足错误,因为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);
    }
}
Run Code Online (Sandbox Code Playgroud)