How to join list of non-string objects using streams
You can just insert a 1
before each element, then skip the first element in the stream.
List<Integer> list2 = list.stream()
.flatMap(i -> Stream.of(1, i))
.skip(1)
.collect(Collectors.toList());
As you've said you don't want to handle only Integer
s, have a look at this more generic solution:
public static <T> List<T> insertBetween(T t, List<T> list) {
return list.stream()
.flatMap(e -> Stream.of(t, e))
.skip(1)
.collect(Collectors.toList());
}
Which you can call like this:
List<Pojo> result = insertBetween(somePojo, pojos);
But keep in mind that if t
is not immutable you can get rather unusual behaviour, as you're simply inserting a reference to t
between each element.
You could overcome this by using a Supplier<T> s
instead of directly T t
. That way you could change the flatMap
to:
.flatMap(e -> Stream.of(s.get(), e))
Which could then be called like this:
List<Pojo> result = insertBetween(() -> new Pojo(), pojos);
You could do this with a custom collector, although I doubt this will be any better than using straight-forward loops:
List<Integer> listWithOnes =
list.stream().collect(
Collector.of(
ArrayList::new,
(result, e) -> {
if (!result.isEmpty()) {
result.add(1);
}
result.add(e);
},
(left, right) -> {
left.add(1);
left.addAll(right);
return left;
}
)
);