2016-12-16 33 views
0

我正在寫一個java函數。該函數的返回類型是ArrayList<String>
當返回的ArrayList有近100萬個元素時,可能會出現這種情況,它會穿過可用RAM並拋出異常。
我該如何處理這種情況。我不希望代碼由於例外而中斷。
有沒有一種方法可以指定抽取特定數量的元素,然後丟棄它們並處理接下來的幾個元素......就像緩衝區大小一樣?
下面是代碼我在做什麼:如何拉取ArrayList中的數據,直到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

你可以給一個足夠大的容量到ArrayList構造函數,所以舊陣列的較大的新陣列無份發生。該方法可能應該不同,使用字節映射內存,也許使用包裝在GZippedOutputStream中的ByteArrayOutputStream。 –

回答

1

您可以嘗試使用分頁的數據:

db.userdetails.find().skip(1000).limit(100); 

在上述情形,你會跳過第10頁,並獲得第11頁。

+0

我會試試這個,讓你知道我在做什麼:) – aiman

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)流:而不是返回一個列表,返回一個流。使用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

+0

我會試試這些,讓你知道結果:) – aiman