1

I want to be able to collect a list of elements of fixed size of 50 elements. Here is how I am currently doing it. I would like to use lambdas if possible.

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);
    }
}
Ele
  • 33,468
  • 7
  • 37
  • 75
BreenDeen
  • 623
  • 1
  • 13
  • 42
  • 1
    What you have is fine, except you forgot to clear/recreate the list. I would use a foreach loop, too. Streams won't help with that scenario. – JB Nizet Dec 28 '17 at 22:12
  • You could adapt [this](https://stackoverflow.com/a/30072617/5457643) answer if you want to use streams. – Turamarth Dec 28 '17 at 22:15

2 Answers2

1

You can do it in that way :

 Iterable<String> iterable = () -> it;
 contactList.addAll(StreamSupport.stream(iterable.spliterator(), false)
            .limit(50)
            .collect(Collectors.toList()));
Daniel Taub
  • 5,133
  • 7
  • 42
  • 72
0

Approach-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());
}

I have taken AtomicInteger to act as mutable counter object. If you are using apache commons lang API then replace AtomicInteger with MutableInt object.

Approach-2

If you can directly use list object rather than using iterator, then we can code like below. Here external counter object not require.

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;
            }))));
sanit
  • 1,646
  • 1
  • 18
  • 21