如何使用lambda表达式在块中拆分Iterable

时间:2017-08-11 15:15:16

标签: java lambda apache-commons iterable sublist

我有 Iterable<CSVRecord> = CSVFormat.RFC4180.withFirstRecordAsHeader().parse(in)(apache commons) 记录是&gt; 10.000.000.000行。以前我用循环计数器和每x行后我处理数据。现在我尝试用Java 8 lambda表达式实现类似的效果。

到目前为止,我想出了这个,但由于我无法找到正确的方法如何在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

2 个答案:

答案 0 :(得分:1)

我不确定您是否可以使用单个lambda表达式执行此操作,但您可以使用.skip().limit()

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 :(得分:0)

我认为针对您的案例的最佳解决方案是分离数据转换阶段和分块。 对于数据转换(记录 - &gt;数组),您可以使用流或并行流。他们在这里闪耀着光芒但是对于流来说,分块并不是好的方案,因为流可以一次产生一个块(通过跳过/限制)。所以你必须为每个块重新创建流。 最好使用简单的循环或一些库api(如推荐的RC)。