2017-08-11 99 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 )