如何使用流连接非字符串对象列表

a.u*_*u.r 6 java java-stream

我有一个对象列表,我想将其映射到由该类型的另一个对象连接的另一个列表。

IE:

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]
Run Code Online (Sandbox Code Playgroud)

这只是一个例子,列表可以是任何类型,而不仅仅是整数。

我的用例是这样的:我有一个 X 类型的对象列表,我需要在该列表的每 2 个项目之间插入一个特定对象。

我知道它可以通过 for 循环轻松完成,但想知道是否有使用Stream.

Lin*_*ica 10

您可以1在每个元素之前插入一个,然后跳过流中的第一个元素。

List<Integer> list2 = list.stream()
    .flatMap(i -> Stream.of(1, i))
    .skip(1)
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

正如你所说,你不想只处理Integers,看看这个更通用的解决方案:

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());
}
Run Code Online (Sandbox Code Playgroud)

你可以这样调用:

List<Pojo> result = insertBetween(somePojo, pojos);
Run Code Online (Sandbox Code Playgroud)

但请记住,如果t不是一成不变的,您可能会得到相当不寻常的行为,因为您只是t在每个元素之间插入一个引用。

您可以通过使用 aSupplier<T> s而不是直接来克服这个问题T t。这样你就可以将其更改flatMap为:

.flatMap(e -> Stream.of(s.get(), e))
Run Code Online (Sandbox Code Playgroud)

然后可以这样调用:

List<Pojo> result = insertBetween(() -> new Pojo(), pojos);
Run Code Online (Sandbox Code Playgroud)