我正在编写一个java函数。此函数的返回类型为ArrayList<String>
可能存在这样的情况:返回的ArrayList
具有接近大约100万个元素,并且它越过可用的RAM,并抛出异常。
我该如何处理这种情况。我不希望代码因例外而中断
有没有办法可以指定拉出特定数量的元素,然后丢弃它们并处理下几个元素......就像缓冲区大小一样?
以下是我正在做的代码:
ArrayList<String> users = getUsers();
...
...
...
private ArrayList<String> getUsers() throws Exception{
//connect to MongoDB
ArrayList<String> userList = new ArrayList<String>();
userList = //get the list of users.
return userList;
}
我想如果返回的列表超出可用内存限制,如果返回的列表太大,那么行ArrayList<String> users = getUsers();
是否会抛出异常?
我该如何处理这种情况?
答案 0 :(得分:2)
有两种标准解决方案可供考虑:
1)分页:将两个数字传递给指定页码和页面大小的方法。在调用代码中,在使用下一页编号再次调用方法之前处理结果:
private void processUsers() {
int pageSize = 42;
// the first page is page 1
int page = 1;
List<String> users = getUsers(page, pageSize);
while(!users.isEmpty()) {
processPage(users);
users = getPage(++page, pageSize);
}
}
private List<String> getPage(int page, int pageSize) {
int maxIndex = countTotalResults() - 1;
int startIndex = Math.MIN((page - 1) * pageSize, maxIndex);
int endIndex = Math.MIN(startIndex + pageSize, maxIndex);
return listUsers(startIndex, endIndex);
}
2)流式传输:不返回List,而是返回Stream。使用Java 8流API处理流。甚至可以让JVM进程并行流,例如:
double average = roster
.parallelStream()
.filter(p -> p.getGender() == Person.Sex.MALE)
.mapToInt(Person::getAge)
.average()
.getAsDouble();
https://docs.oracle.com/javase/tutorial/collections/streams/parallelism.html
答案 1 :(得分:1)
您可以尝试使用以下内容对数据进行分页:
db.userdetails.find().skip(1000).limit(100);
在上面的场景中,您将跳过前10页并获取第11页。