创建非常大的列表块时内存不足
Out of Memory while creating chunks of a very large list
我需要得到 return 由 public API编辑的所有成员的列表。
问题是我不知道任何 ID,但我知道第一个 ID 在 500000000 之后开始,最后一个在 570000000 左右。检查后,我知道这些 ID 是时间戳生成的,但我不知道还有其他信息吗
所以我唯一的办法就是自己去取。
我写了这个:
private List<List<Long>> getFinalList() {
return chunkArrayList(getInitList(), 100);
}
private List<Long> getInitList() {
List<Long> idList = new ArrayList<>();
for (long i = 500000000L; i < 570000000L; i++) {
idList.add(i);
}
return idList;
}
private List<List<Long>> chunkArrayList(List<Long> listToChunk, int chunkSize) {
AtomicInteger counter = new AtomicInteger();
return new ArrayList<>(listToChunk.stream().collect(Collectors.groupingBy(l -> counter.getAndIncrement() / chunkSize)).values());
}
注意:我必须将我的列表分成更小的部分,以便将它们分成多个 API 调用。
我的主要问题是这段代码 return 我遇到了内存不足异常,这是不稳定的。
我怎样才能做这样的过程,同时最有效并避免那些内存问题?
列出 70,000,000 个高度可预测的值有什么意义?如果您将分块列表传递给 API,则只需根据需要构建那些较小的列表。您需要跟踪的只是接下来要使用的号码。
您可以将 return 类型从列表更改为流:
private Stream<List<Long>> getFinalList() {
return chunkArrayList(getInitList(), 100);
}
private Stream<Long> getInitList() {
return LongStream.rangeClosed(500000000L, 570000000L).boxed();
}
public Stream<List<Long>> chunkArrayList(Stream<Long> stream, int chunkSize) {
AtomicInteger counter = new AtomicInteger(0);
return stream.collect(Collectors.groupingBy(x -> counter.getAndIncrement() / chunkSize))
.values().stream();
}
但是正如@Zag 已经提到的那样,没有必要这样做。
类似的内容可能会有所帮助
public static void makeAnAPICallWithChunks(int chunkSize){
LongStream.iterate(500000000L, x -> x + chunkSize)
.boxed()
.takeWhile(x -> x < 570000000L)
.forEach(x -> {System.out.println(x + " to " + (x + chunkSize-1));});
}
我需要得到 return 由 public API编辑的所有成员的列表。
问题是我不知道任何 ID,但我知道第一个 ID 在 500000000 之后开始,最后一个在 570000000 左右。检查后,我知道这些 ID 是时间戳生成的,但我不知道还有其他信息吗
所以我唯一的办法就是自己去取。
我写了这个:
private List<List<Long>> getFinalList() {
return chunkArrayList(getInitList(), 100);
}
private List<Long> getInitList() {
List<Long> idList = new ArrayList<>();
for (long i = 500000000L; i < 570000000L; i++) {
idList.add(i);
}
return idList;
}
private List<List<Long>> chunkArrayList(List<Long> listToChunk, int chunkSize) {
AtomicInteger counter = new AtomicInteger();
return new ArrayList<>(listToChunk.stream().collect(Collectors.groupingBy(l -> counter.getAndIncrement() / chunkSize)).values());
}
注意:我必须将我的列表分成更小的部分,以便将它们分成多个 API 调用。
我的主要问题是这段代码 return 我遇到了内存不足异常,这是不稳定的。
我怎样才能做这样的过程,同时最有效并避免那些内存问题?
列出 70,000,000 个高度可预测的值有什么意义?如果您将分块列表传递给 API,则只需根据需要构建那些较小的列表。您需要跟踪的只是接下来要使用的号码。
您可以将 return 类型从列表更改为流:
private Stream<List<Long>> getFinalList() {
return chunkArrayList(getInitList(), 100);
}
private Stream<Long> getInitList() {
return LongStream.rangeClosed(500000000L, 570000000L).boxed();
}
public Stream<List<Long>> chunkArrayList(Stream<Long> stream, int chunkSize) {
AtomicInteger counter = new AtomicInteger(0);
return stream.collect(Collectors.groupingBy(x -> counter.getAndIncrement() / chunkSize))
.values().stream();
}
但是正如@Zag 已经提到的那样,没有必要这样做。
类似的内容可能会有所帮助
public static void makeAnAPICallWithChunks(int chunkSize){
LongStream.iterate(500000000L, x -> x + chunkSize)
.boxed()
.takeWhile(x -> x < 570000000L)
.forEach(x -> {System.out.println(x + " to " + (x + chunkSize-1));});
}