Expand Authors Top

If you have a few years of experience in the Java ecosystem and you’d like to share that with the community, have a look at our Contribution Guidelines.

November Discount Launch 2022 – Top
We’re finally running a Black Friday launch. All Courses are 30% off until next Friday:

>> GET ACCESS NOW

November Discount Launch 2022 – TEMP TOP (NPI)
We’re finally running a Black Friday launch. All Courses are 30% off until next Friday:

>> GET ACCESS NOW

Expanded Audience – Frontegg – Security (partner)
announcement - icon User management is very complex, when implemented properly. No surprise here.

Not having to roll all of that out manually, but instead integrating a mature, fully-fledged solution - yeah, that makes a lot of sense.
That's basically what Frontegg is - User Management for your application. It's focused on making your app scalable, secure and enjoyable for your users.
From signup to authentication, it supports simple scenarios all the way to complex and custom application logic.

Have a look:

>> Elegant User Management, Tailor-made for B2B SaaS

1. Overview

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.

2. Prepending

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

@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

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

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

@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

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.

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.

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.

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

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.

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.

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

November Discount Launch 2022 – Bottom
We’re finally running a Black Friday launch. All Courses are 30% off until next Friday:

>> GET ACCESS NOW

Generic footer banner
Comments are closed on this article!