I am trying to learn java - stream. I am able to do simple iteration / filter / map / collection etc.
When I was kind of trying to collect every 3 elements and print as shown here in this example, [collect every 3 elements and print and so on...]
List<String> list = Arrays.asList("a","b","c","d","e","f","g","h","i","j");
int count=0;
String append="";
for(String l: list){
if(count>2){
System.out.println(append);
System.out.println("-------------------");
append="";
count=0;
}
append = append + l;
count++;
}
System.out.println(append);
output:
abc
-------------------
def
-------------------
ghi
-------------------
j
I am not getting any clue how to do this using stream. Should i implement my own collector to achieve this?
You can actually use an IntStream
to simulate your list's pagination.
List<String> list = Arrays.asList("a","b","c","d","e","f","g","h","i","j");
int pageSize = 3;
IntStream.range(0, (list.size() + pageSize - 1) / pageSize)
.mapToObj(i -> list.subList(i * pageSize, Math.min(pageSize * (i + 1), list.size())))
.forEach(System.out::println);
which outputs:
[a, b, c]
[d, e, f]
[g, h, i]
[j]
If you want to generate Strings, you can use String.join
since you are dealing with a List<String>
directly:
.mapToObj(i -> String.join("", list.subList(i * pageSize, Math.min(pageSize * (i + 1), list.size()))))
If you have Guava in your project, you can use Iterables.partition
method:
import com.google.common.collect.Iterables;
import com.google.common.collect.Streams;
...
Stream<List<String>> stream = Streams.stream(Iterables.partition(list, 3));
You can create your own Collector
. The easiest way is to call Collector.of()
.
Since your use case requires values to be processed in order, here is an implementation that simply doesn't support parallel processing.
public static Collector<String, List<List<String>>, List<List<String>>> blockCollector(int blockSize) {
return Collector.of(
ArrayList<List<String>>::new,
(list, value) -> {
List<String> block = (list.isEmpty() ? null : list.get(list.size() - 1));
if (block == null || block.size() == blockSize)
list.add(block = new ArrayList<>(blockSize));
block.add(value);
},
(r1, r2) -> { throw new UnsupportedOperationException("Parallel processing not supported"); }
);
}
Test
List<String> input = Arrays.asList("a","b","c","d","e","f","g","h","i","j");
List<List<String>> output = input.stream().collect(blockCollector(3));
output.forEach(System.out::println);
Output
[a, b, c]
[d, e, f]
[g, h, i]
[j]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With