How to Add a Single Element to a Stream – 如何将单个元素添加到一个流中

最后修改: 2017年 5月 22日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this quick article, we’re going to take a look at how to add an element to a Java 8 Stream which is not as intuitive as adding an element to a normal collection.

在这篇快速文章中,我们将看看如何向Java 8 Stream添加一个元素,这不像向普通集合添加一个元素那么直观。

2. Prepending

2.预设

We can easily prepend a given element to a Stream by invoking the static Stream.concat() method:

我们可以通过调用静态的Stream.concat()方法,轻松地将一个给定的元素预置到Stream中。

@Test
public void givenStream_whenPrependingObject_thenPrepended() {
    Stream<Integer> anStream = Stream.of(1, 2, 3, 4, 5);

    Stream<Integer> newStream = Stream.concat(Stream.of(99), anStream);

    assertEquals(newStream.findFirst().get(), (Integer) 99);
}

3. Appending

3.附加

Likewise, to append an element to the end of a Stream, we just need to invert the arguments.

同样地,要把一个元素追加到Stream的末尾,我们只需要反转参数。

Keep in mind that Streams can represent infinite sequences so there are scenarios when you might never get to your new element:

请记住,Streams可以代表无限的序列,所以在有些情况下,你可能永远也到不了你的新元素。

@Test
public void givenStream_whenAppendingObject_thenAppended() {
    Stream<String> anStream = Stream.of("a", "b", "c", "d", "e");

    Stream<String> newStream = Stream.concat(anStream, Stream.of("A"));

    List<String> resultList = newStream.collect(Collectors.toList());
 
    assertEquals(resultList.get(resultList.size() - 1), "A");
}

4. At a Specific Index

4.在一个特定的指数

Stream (java.util.stream) in Java is a sequence of elements supporting sequential and parallel aggregate operations. There is no function for adding a value to a specific index since it’s not designed for such a thing. However, there are a couple of ways to achieve it.

Java中的Stream(java.util.stream)是一个支持顺序和平行聚合操作的元素序列。没有向特定索引添加值的功能,因为它不是为这种事情设计的。然而,有几种方法可以实现它。

One approach is to use a terminal operation to collect the values of the stream to an ArrayList, and then simply use add(int index, E element) method. Keep in mind that this will give you the desired result but you will also lose the laziness of a Stream because you need to consume it before inserting a new element.

一种方法是使用终端操作将流的值收集到一个ArrayList,然后简单地使用add(int index, E element)方法。请记住,这将给你带来期望的结果,但你也将失去Stream的懒惰,因为你需要在插入一个新元素之前消耗它。

The alternative is to use Spliterator and iterate the elements sequentially to the target index (using the iterator of the Spliterator class.) The concept is to break the stream into two streams (A and B). Stream A starts from index 0 to the target index, and stream B is the remaining element. Then add the element to stream A, and finally concatenate streams A and B.

另一种方法是使用Spliterator,并依次迭代元素到目标索引(使用Spliterator类的迭代器。)其概念是将流分成两个流(A和B)。A流从索引0开始到目标索引,B流是剩余的元素。然后将元素添加到流A中,最后将流A和流B串联起来。

In this case, since the stream is not consumed greedily, it is still partially lazy:

在这种情况下,由于流没有被贪婪地消耗,它仍然是部分懒惰的。

private static  Stream insertInStream(Stream stream, T elem, int index) {
    Spliterator spliterator = stream.spliterator();
    Iterator iterator = Spliterators.iterator(spliterator);

    return Stream.concat(Stream.concat(Stream.generate(iterator::next)
      .limit(index), Stream.of(elem)), StreamSupport.stream(spliterator, false));
}

Now, let’s test our code to ensure everything is working as expected:

现在,让我们测试一下我们的代码,以确保一切都在按预期工作。

@Test
public void givenStream_whenInsertingObject_thenInserted() {
    Stream<Double> anStream = Stream.of(1.1, 2.2, 3.3);
    Stream<Double> newStream = insertInStream(anStream, 9.9, 3);

    List<Double> resultList = newStream.collect(Collectors.toList());
 
    assertEquals(resultList.get(3), (Double) 9.9);
}

5. Conclusion

5.结论

In this short article, we’ve seen how to add a single element to a Stream, be it at the beginning, at the end, or at a given position.

在这篇短文中,我们看到了如何向Stream添加一个单一的元素,无论是在开头、结尾,还是在指定的位置。

Keep in mind that although prepending an element works for any Stream, adding it to the end or at a specific index only works for finite streams.

请记住,尽管预置一个元素对任何Stream都有效,把它加到最后或在一个特定的索引处,只对有限的流有效。

As always, complete source code can be found over on Github.

一如既往,完整的源代码可以在Github上找到over