Java stream concat three streams

How to Merge Multiple Collections in Java

Learn different techniques to Merge or Concatenate multiple collections together in Java with the help of practical examples.

Overview

There are different ways available to merge or concatenate multiple Java Collections together. Java Collection is the parent interface of all collections available in Java.

Concatenate Collections using Java Streams

With Java 8 Streams, there are two basic ways of merging collections. Next, we will look at both of them one by one.

Concatenate Using Java Streams flatMap Method

We will use flatMap method of Java Streams to merge two collections.

Before we do that, the following are the two collections that we want to join together.

Collection collection1 = List.of(1, 2, 3); Collection collection2 = List.of(97, 98, 99);Code language: Java (java)

Next is how we can use flatMap to combine these two collections.

Collection merged = Stream.of(collection1, collection2) .flatMap(Collection::stream) .collect(Collectors.toList());Code language: Java (java)

First, we are creating a stream of two collections. That means the stream will have only two elements, which are the two collections. After which, we use flatMap to merge them to create combined steam of their elements. Finally, we are collecting the stream elements together in an ArrayList .

Читайте также:  Using postgresql with java

The output we get looks like this:

Concatenate using Java Streams Concat Method

The concat method of Streams interface merges elements from multiple streams to form a stream of combined elements.

Collection merged = Stream .concat(collection1.stream(), collection2.stream()) .collect(Collectors.toList());Code language: Java (java)

Here, we are creating individual streams from both of our collections and using the concat method to form a single stream of their elements combined. Lastly, we are collecting the elements together in an ArrayList.

Concatenate Collections in Plain Java

The Java Collections interface defines addAll method. We can call this method on one collection and pass another collection as an argument.

However, with this method, this collection will be modified. Hence we can’t use the Immutable List that we used in the previous examples.

Collection collection1 = new ArrayList<>(Arrays.asList(1, 2, 3)); Collection collection2 = new ArrayList<>(Arrays.asList(97, 98, 99)); boolean hasModified = collection1.addAll(collection2);Code language: Java (java)

We have created two ArrayList instances and executed addAll on one of them. The boolean result denotes if the merge was successful.

Concatenate Collections using Guava

We have seen Java’s ways of merging or concatenating collections together. Now, we will see how can we use the Guava library to do so.

Before that, make sure you have Guava dependency in your build.

Concatenate using Iterables addAll method

The Iterables class has addAll method which accepts two collection arguments. In doing so, the method dumps the second collection into the first one.

Collection collection1 = new ArrayList<>(Arrays.asList(1, 2, 3)); Collection collection2 = List.of(2, 97, 98, 99); boolean hasModified = Iterables.addAll(collection1, collection2);Code language: Java (java)

Note that, with this method, the first collection is modified. That is why our first collection is not Immutable. The resulting boolean value denotes if the first collection is altered or not.

Concatenate Iterables using concat Method

The Iterables class provides concat method that accepts n number of Iterable instances and returns a new Iterable instance having all elements concatenated.

Collection collection1 = List.of(1, 2, 3); Collection collection2 = List.of(2, 97, 98, 99); Iterable merged = Iterables.concat(collection1, collection2);Code language: Java (java)

Note that this method creates a new instance; hence we can pass Immutable Lists.

Concatenate Collections using Apache Commons Collections

Similarly, we can use Apache Commons Collections Library to merge collections.

We need to add Apache Commons Collections dependencies in your build.

Merge Collections using CollectionUtils

The union methods from the CollectionUtils class can merge two collections to form a third one.

Collection collection1 = List.of(1, 1, 2, 3, 4); Collection collection2 = List.of(2, 97, 98, 99, 100); Collection merged = CollectionUtils .union(collection1, collection2);Code language: Java (java)

However, there are two interesting facts about this method.

  1. The union method first copies all the elements from the first collection. After that, it only picks those elements from the second collection which are not part of the first.
  2. Unlike other ways, which concatenate elements of the second collection after the end of the first, the union method merges elements. To understand this, we will print the combined collection.

The output shows how the elements from both collections are merged together, and also, the number 2 from the second List is not copied.

Concatenate Iterables using IterableUtils

The IterableUtils class from Apache Commons Library provides a way to concatenate two iterables together.

Collection collection1 = List.of(1, 1, 2, 3, 4); Collection collection2 = List.of(2, 97, 98, 99, 100); Iterable merged = IterableUtils .chainedIterable(collection1, collection2);Code language: Java (java)

Unlike the union method of CollectionUtils, this method concatenates elements of the second iterable at the end of the first one.

Concatenate Collections without Duplicates

Using Java Streams API, we can combine multiple collections and form a new collection of unique elements. To know more ways of removing duplicates from a List, consider reading our detailed tutorial Removing Duplicate Elements from Java List.

We have already seen an example of the Java Streams Concat Method. We will add distinct to the stream pipeline to filter out duplicate elements.

Collection collection1 = List.of(1, 2, 3, 3); Collection collection2 = List.of(2, 97, 98, 99); Iterable merged = Streams .concat(collection1.stream(), collection2.stream()) .distinct() .collect(Collectors.toList());Code language: Java (java)

Summary

In this tutorial, we thoroughly understood how to merge multiple Java Collections to form a collection of combined elements. We covered plenty of examples using Java Streams, plain Java, Guava library, and Apache Commons Collections library. Lastly, we saw Java 8 streams way of concatenating collections without duplicate elements.

Источник

Merging Streams in Java

announcement - icon

As always, the writeup is super practical and based on a simple application that can work with documents with a mix of encrypted and unencrypted fields.

We rely on other people’s code in our own work. Every day.

It might be the language you’re writing in, the framework you’re building on, or some esoteric piece of software that does one thing so well you never found the need to implement it yourself.

The problem is, of course, when things fall apart in production — debugging the implementation of a 3rd party library you have no intimate knowledge of is, to say the least, tricky.

Lightrun is a new kind of debugger.

It’s one geared specifically towards real-life production environments. Using Lightrun, you can drill down into running applications, including 3rd party dependencies, with real-time logs, snapshots, and metrics.

Learn more in this quick, 5-minute Lightrun tutorial:

announcement - icon

Slow MySQL query performance is all too common. Of course it is. A good way to go is, naturally, a dedicated profiler that actually understands the ins and outs of MySQL.

The Jet Profiler was built for MySQL only, so it can do things like real-time query performance, focus on most used tables or most frequent queries, quickly identify performance issues and basically help you optimize your queries.

Critically, it has very minimal impact on your server’s performance, with most of the profiling work done separately — so it needs no server changes, agents or separate services.

Basically, you install the desktop application, connect to your MySQL server, hit the record button, and you’ll have results within minutes:

announcement - icon

DbSchema is a super-flexible database designer, which can take you from designing the DB with your team all the way to safely deploying the schema.

The way it does all of that is by using a design model, a database-independent image of the schema, which can be shared in a team using GIT and compared or deployed on to any database.

And, of course, it can be heavily visual, allowing you to interact with the database using diagrams, visually compose queries, explore the data, generate random data, import data or build HTML5 database reports.

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

> CHECK OUT THE COURSE

1. Overview

In this quick article, we explain different ways of merging Java Streams – which is not a very intuitive operation.

2. Using Plain Java

The JDK 8 Stream class has some useful static utility methods. Let’s take a closer look at the concat() method.

2.1. Merging Two Streams

The simplest way to combine 2 Streams is to use the static Stream.concat() method:

@Test public void whenMergingStreams_thenResultStreamContainsElementsFromBoth() < Streamstream1 = Stream.of(1, 3, 5); Stream stream2 = Stream.of(2, 4, 6); Stream resultingStream = Stream.concat(stream1, stream2); assertEquals( Arrays.asList(1, 3, 5, 2, 4, 6), resultingStream.collect(Collectors.toList())); > 

2.2. Merging Multiple Streams

When we need to merge more than 2 Streams, things become a bit more complex. One possibility is to concatenate the first two streams, then concatenate the result with the next one and so on.

The next code snippet shows this in action:

@Test public void given3Streams_whenMerged_thenResultStreamContainsAllElements() < Streamstream1 = Stream.of(1, 3, 5); Stream stream2 = Stream.of(2, 4, 6); Stream stream3 = Stream.of(18, 15, 36); Stream resultingStream = Stream.concat( Stream.concat(stream1, stream2), stream3); assertEquals( Arrays.asList(1, 3, 5, 2, 4, 6, 18, 15, 36), resultingStream.collect(Collectors.toList())); > 

As we can see, this approach becomes unfeasible for more streams. Of course, we can create intermediate variables or helper methods to make it more readable, but here is a better option:

@Test public void given4Streams_whenMerged_thenResultStreamContainsAllElements() < Streamstream1 = Stream.of(1, 3, 5); Stream stream2 = Stream.of(2, 4, 6); Stream stream3 = Stream.of(18, 15, 36); Stream stream4 = Stream.of(99); Stream resultingStream = Stream.of( stream1, stream2, stream3, stream4) .flatMap(i -> i); assertEquals( Arrays.asList(1, 3, 5, 2, 4, 6, 18, 15, 36, 99), resultingStream.collect(Collectors.toList())); > 
  • We first create a new Stream containing the 4 Streams, which results in a Stream>
  • Then we flatMap() this into a Stream using the identity function

3. Using StreamEx

StreamEx is an open-source Java library that extends possibilities of Java 8 Streams. It uses the StreamEx class as an enhancement to the JDK’s Stream interface.

3.1. Merging Streams

The StreamEx library allows us to merge streams using the append() instance method:

@Test public void given4Streams_whenMerged_thenResultStreamContainsAllElements() < Streamstream1 = Stream.of(1, 3, 5); Stream stream2 = Stream.of(2, 4, 6); Stream stream3 = Stream.of(18, 15, 36); Stream stream4 = Stream.of(99); Stream resultingStream = StreamEx.of(stream1) .append(stream2) .append(stream3) .append(stream4); assertEquals( Arrays.asList(1, 3, 5, 2, 4, 6, 18, 15, 36, 99), resultingStream.collect(Collectors.toList())); > 

Since it is an instance method, we can easily chain it and append multiple streams.

Note that we could also create a List out of the stream by using toList() if we type the resultingStream variable to the StreamEx type.

3.2. Merging Streams Using prepend()

StreamEx also contains a method that adds elements before one another called prepend():

@Test public void given3Streams_whenPrepended_thenResultStreamContainsAllElements() < Streamstream1 = Stream.of("foo", "bar"); Stream openingBracketStream = Stream.of("["); Stream closingBracketStream = Stream.of("]"); Stream resultingStream = StreamEx.of(stream1) .append(closingBracketStream) .prepend(openingBracketStream); assertEquals( Arrays.asList("[", "foo", "bar", "]"), resultingStream.collect(Collectors.toList())); > 

4. Using Jooλ

jOOλ is a JDK 8 compatible library that provides useful extensions to the JDK. The most important stream abstraction here is called Seq. Note that this is a sequential and ordered stream, so calling parallel() will have no effect.

4.1. Merging Streams

Just like the StreamEx library, jOOλ has an append() method:

@Test public void given2Streams_whenMerged_thenResultStreamContainsAllElements() < Streamseq1 = Stream.of(1, 3, 5); Stream seq2 = Stream.of(2, 4, 6); Stream resultingSeq = Seq.ofType(seq1, Integer.class) .append(seq2); assertEquals( Arrays.asList(1, 3, 5, 2, 4, 6), resultingSeq.collect(Collectors.toList())); > 

Also, there is a convenience toList() method if we type the resultingSeq variable to the jOOλ Seq type.

4.2. Merging Streams With prepend()

As expected, since an append() method exists, there is also a prepend() method in jOOλ:

@Test public void given3Streams_whenPrepending_thenResultStreamContainsAllElements() < Streamseq = Stream.of("foo", "bar"); Stream openingBracketSeq = Stream.of("["); Stream closingBracketSeq = Stream.of("]"); Stream resultingStream = Seq.ofType(seq, String.class) .append(closingBracketSeq) .prepend(openingBracketSeq); Assert.assertEquals( Arrays.asList("[", "foo", "bar", "]"), resultingStream.collect(Collectors.toList())); > 

5. Conclusion

We saw that merging streams is relatively straightforward using JDK 8. When we need to do a lot of merging, it might be beneficial to use the StreamEx or jOOλ library for the sake of readability.

You can find the source code over on GitHub.

announcement - icon

Slow MySQL query performance is all too common. Of course it is. A good way to go is, naturally, a dedicated profiler that actually understands the ins and outs of MySQL.

The Jet Profiler was built for MySQL only, so it can do things like real-time query performance, focus on most used tables or most frequent queries, quickly identify performance issues and basically help you optimize your queries.

Critically, it has very minimal impact on your server’s performance, with most of the profiling work done separately — so it needs no server changes, agents or separate services.

Basically, you install the desktop application, connect to your MySQL server, hit the record button, and you’ll have results within minutes:

Источник

Оцените статью