我有一个项目列表,我需要每次最多调用30个函数。这就是我正在做的事情:
final int maxItemsPerRequest = 30;
List<Item> itemsToProcess = new ArrayList<>();
for (Item item : itemsList) {
itemsToProcess.add(item);
if (itemsToProcess.size() % maxItemsPerRequest == 0) {
processItem(itemsToProcess);
itemsToProcess = new ArrayList<>();
}
}
if (itemsToProcess.size() > 0)
processItem(itemsToProcess);
我觉得最后一次检查(.size()&gt; 0)有点味道。
有关其他方式的任何建议吗?
答案 0 :(得分:3)
如果您还没有使用Java 8,那么使用第三方库可能是最简单,最快捷的选择。
在这种特殊情况下,您可以从Guava的Lists.partition方法中受益,该方法可以按如下方式使用:
for (List<Foo> itemsPartition : Lists.partition(itemsList, 30)) {
processItem(itemsPartition);
}
答案 1 :(得分:2)
想想你想做什么。
您有List
个尺寸为x
的东西。您希望将此列表拆分为大小为<= y
的块。现在,有一种神奇的subList
方法。这会返回列表[i, j)
的一部分的视图。
似乎解决方案应该是显而易见的,将输入拆分为List<List<>>
块使用:
final int blockSize = 5;
List<List<String>> chunks = new ArrayList<>();
for (int i = 0; i < items.size(); i += blockSize) {
chunks.add(items.subList(i, Math.min(i + blockSize, items.size())));
}
没有不必要的新列表,最后没有奇怪的size > 0
。显然,您可以直接调度到您的处理方法,而不是累积到chunks
。
Java 8中的一个小演示:
public static void main(String[] args) throws ParseException {
List<String> items = Stream.generate(() -> "a").limit(47).collect(toList());
final int blockSize = 5;
List<List<String>> chunks = new ArrayList<>();
for (int i = 0; i < items.size(); i += blockSize) {
chunks.add(items.subList(i, Math.min(i + blockSize, items.size())));
}
chunks.forEach(System.out::println);
}
输出:
[a, a, a, a, a]
[a, a, a, a, a]
[a, a, a, a, a]
[a, a, a, a, a]
[a, a, a, a, a]
[a, a, a, a, a]
[a, a, a, a, a]
[a, a, a, a, a]
[a, a, a, a, a]
[a, a]
答案 2 :(得分:2)
如果您有一个大清单,并希望一次处理30个项目,那么使用subList
可能最容易。
final int BUCKET_SIZE = 30;
final List<Whatever> list = bigListOfEverything();
final int size = list.size();
for (int i = 0; i < size; i += BUCKET_SIZE) {
final List<Whatever> subList = list.subList(i, (i + BUCKET_SIZE) > size ? size : (i + BUCKET_SIZE));
processOneBucket(subList);
}
如果您一次生成一个项目,并且您没有完整列表,则每次达到预期的存储桶大小时,建立一个列表并将其传递以进行处理会更容易,如果在循环结束时留下一个非空桶。这就是你目前正在做的事情,如果你没有完整的清单,这是一个很好的方法。