2017-08-11 22 views
1

我有 Iterable<CSVRecord> = CSVFormat.RFC4180.withFirstRecordAsHeader().parse(in)(apache共享) 記錄這是> 10.000.000.000行。以前我曾經用循環計數器,並在每個x行之後處理數據。現在我試圖用Java 8 lambda表達式實現類似的效果。如何分割與lambda表達式塊Iterable

到目前爲止,我想出了這一點,但它運行的內存,因爲我無法找到正確的方式如何分割,在subList

Iterable<List<?>> params = new ArrayList<>(StreamSupport 
       .stream(records.spliterator(), true) 
       .map(r -> Arrays.asList(
         r.get("name"), 
         r.get("surname"), 
         r.get("something"), 
       )) 
       .collect(Collectors.toList()).subList(0, 20000)); 

子列表在結尾不工作:(

我只需要概念的一些證據如何分割Iterable - 例如,正確的地方在哪裏把subList

+0

是「記錄」列表嗎?如果是這樣,也許你可以使用guava中的Lists.partition(在Iterables中也有一個版本)。 – 2017-08-11 15:20:04

+0

更新了我的問題。調試器說,記錄是'org.apache.commons.csv.CSVParser' – lapkritinis

回答

1

我不知道,如果你可以用一個單一的λ快報做到這一點,但您可以使用.skip()和01?:

int maxSize = 20000; 
int currentOffset = 0; // Increment by maxSize each iteration  
Iterable<List<?>> params = new ArrayList<>(StreamSupport 
          .stream(records.spliterator(), true) 
          .skip(currentOffset) 
          .limit(maxSize) 
          .map(r -> Arrays.asList(
            r.get("name"), 
            r.get("surname"), 
            r.get("something"), 
          )) 
          .collect(Collectors.toList()) 
+1

這工作。如果有更好的解決方案出現,我會留下一天的問題,但到目前爲止,您的答案最符合我的要求。謝謝! – lapkritinis

0

我覺得你的情況下,最好的解決辦法就是分離數據轉換級和分塊。 對於數據轉換(記錄 - >數組),您可以使用流或並行流。他們在這裏閃閃發光。但是對於這些流來說,分塊並不是好場景。 聽到它會更好地使用簡單的循環或一些庫API(如RC建議)。

0

這並不回答組塊的問題,但是......考慮購買更多的內存。如果這是問題集的典型大小。 RAM可能會花費比額外思考時間便宜的代價,從而不斷編寫高效節省內存的程序。

+0

也許,但我喜歡編寫內存高效的程序:) – lapkritinis

+1

你永遠無法在微軟那裏以這種態度找到工作。 –

1

嗨,我不確定它看起來不錯,但這是處理事情的另一種方式。

//that can be CsvParser not List 
List<Integer> collection = Arrays.asList(1, 2, 4, 5, 2, 1, 2, 4, 5); 

int limit = 2; 
int size = collection.size(); 

long maxPartIndex = (long) Math.ceil((double) size/ limit); 

LongStream.range(0, maxPartIndex) 
    .mapToObj(partIndex -> getPart(collection.spliterator(), partIndex, limit)) 
    .forEach(System.out::println); 

....

private static <T> List<T> getPart(Spliterator<T> stream, long index, long size) { 
    return StreamSupport.stream(stream, false) 
    .skip(index * size) 
    .limit(size) 
    .collect(Collectors.toList()); 
} 

輸出:

(1,2) (4,5) (2,1) (2,4) (5 )