Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to join list of non-string objects using streams [duplicate]

I have a list of Objects that I want to map to another list that is joined by another object of that type.

i.e:

List<Integer> list = List.of(5,6,7,8);
// is it possible to insert `1` between every item in the list?
// joined list = [5,1,6,1,7,1,8]

This is just an example, the list can be of any type not just Integer.

My use case is this: I have a list of objects of type X, and I need to insert a certain object between every 2 items of that list.

I know it can be easily done by a for-loop, but wondering if there's a solution using Stream.

like image 656
a.u.r Avatar asked Jun 18 '20 13:06

a.u.r


1 Answers

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 Integers, 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);
like image 95
Lino Avatar answered Sep 18 '22 02:09

Lino