如何将Iterator值收集到50个元素的列表中

时间:2017-12-28 22:05:07

标签: java lambda collections

我希望能够收集固定大小为50个元素的元素列表。这是我目前正在做的事情。如果可能,我想使用lambdas。

List<Contact> contactList=getContacts();

Iterator<Contact> it=contactList.iterator();

List<Contact> batch=new ArrayList<>();
while(it.hasNext()) {
    if(batch.size()<50) { 
        batch.add(it.next())
    } else {
        processBatch(batch);
    }

    //When iterator has less than 50 elements
    if (!it.hasNext() && batch.size()<50) {
        processBatch(batch);
    }
}

2 个答案:

答案 0 :(得分:1)

你可以这样做:

 Iterable<String> iterable = () -> it;
 contactList.addAll(StreamSupport.stream(iterable.spliterator(), false)
            .limit(50)
            .collect(Collectors.toList()));

答案 1 :(得分:0)

<强>方法-1

public static void main(String[] args) {
    List<Integer> list = IntStream.range(0, 280).boxed().collect(toList());
    AtomicInteger count = new AtomicInteger();
    StreamSupport.stream(list.spliterator(), false)
            .collect(groupingBy(e -> count.getAndIncrement() / 50, 
                 collectingAndThen(toList(), l -> {
                                 processBatch(l);
                                 return null;
                  })));
}

public static <T extends Object> void processBatch(List<T> list) {
    System.out.println(list.size());
}

我已将AtomicInteger作为可变计数器对象。如果您使用的是apache commons lang API,则将AtomicInteger替换为MutableInt对象。

<强>方法-2

如果你可以直接使用list对象而不是使用iterator,那么我们可以像下面这样编写代码。这里不需要外部计数器对象。

IntStream.range(0, list.size()).mapToObj(i -> new Object[] { i, list.get(i) }).collect(groupingBy(
            arr -> (int) arr[0] / 50, Collectors.mapping(arr -> arr[1], collectingAndThen(toList(), l -> {
                processBatch(l);
                return null;
            }))));