1. Overview
In this article, you are going to learn the java 8 Stream api concat() method to merge two streams into one stream. In the end, merged streams or collections will have all elements from both streams.
Let us explore the different ways to merge the streams using java 8 stream api.
2. Java 8 Stream API concat() Syntax
The following concat() syntax from api.
static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)
Stream.concat() method takes two Streams as input and returns one steam with all the values.
3. Java 8 Stream API concat() Rules
Stream.concat() method creates a lazily concatenated stream whose elements are all the elements of the first stream followed by all the elements of the second stream.
The resulting stream is ordered if both of the input streams are ordered.
The parallel stream is returned if either of the input streams in parallel.
When the resulting stream is closed, the close handlers for both input streams are invoked.
If used concat() excessively in repeated concatenation or chaining then will cause deep call chains and generates StackOverflowException.
4. Example 1 To Merge Two Streams in Java 8
Let us write an example program to merge two streams into a single stream in java 8.
import java.util.stream.Stream;
public class StreamJoinTwoStreams {
public static void main(String[] args) {
// Creating stream 1
Stream<Integer> stream1 = Stream.of(2, 4, 6, 8, 10);
// Creating stream 2
Stream<Integer> stream2 = Stream.of(1, 3, 5, 7, 9);
// Merging two streams in java 8 using concat method
Stream<Integer> mergedStream = Stream.concat(stream1, stream2);
// printing merged stream values
System.out.println("Merged stream values are ");
mergedStream.forEach(even -> System.out.println(even));
}
}
Output:
Merged stream values are 2 4 6 8 10 1 3 5 7 9
5. Example 2 To Merge Two Streams and Sort in Java 8
import java.util.stream.Stream;
public class StreamConcatSortExample {
public static void main(String[] args) {
// Creating odd numbers stream
Stream<Integer> oddStream = Stream.of(1, 3, 5, 7, 9);
// Creating even numbers stream
Stream<Integer> evenStream = Stream.of(2, 4, 6, 8);
// Merging two streams in java 8 using concat() method
Stream<Integer> sortedStream = Stream.concat(oddStream, evenStream).sorted();
// printing sorted merged stream values
System.out.println("Sorted resulting stream values are ");
sortedStream.forEach(even -> System.out.println(even));
}
}
Sorted resulting stream values are
1
2
3
4
5
6
7
8
9
6. Example 3 To Merge List of Strings in Java 8
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class StreamMergeListStrings {
public static void main(String[] args) {
// Creating list 1 with string values
List<String> list1 = Arrays.asList("hello", "how", "are", "you", "doing", "?");
// Creating list 2 with string values
List<String> list2 = Arrays.asList("I", "am", "doing", "great", "!");
// Merging list of strings with concat method
List<String> mergedList = Stream.concat(list1.stream(), list2.stream()).collect(Collectors.toList());
// Merged list values
System.out.println("Final merged list values are ");
mergedList.forEach(finalValue -> System.out.println(finalValue));
}
}
Final merged list values are
hello
how
are
you
doing
?
I
am
doing
great
!
7. Example 4 To Merge Multiple Streams
import static java.util.stream.Stream.concat;
import java.util.stream.Stream;
public class MultipleStreamMergeExample {
public static void main(String[] args) {
// Creating stream 1
Stream<Integer> stream1 = Stream.of(1, 2, 3);
// Creating stream 2
Stream<Integer> stream2 = Stream.of(4, 5, 6);
// Creating stream 3
Stream<Integer> stream3 = Stream.of(7, 8, 9);
// Creating stream 4
Stream<Integer> stream4 = Stream.of(10, 11, 12);
// Creating stream 5
Stream<Integer> stream5 = Stream.of(13, 14, 15);
Stream<Integer> final5StreamsMergeREsult = Stream.concat(stream1,concat(stream2, concat(stream3, concat(stream4, stream5))));
// printing sorted merged stream values
System.out.println("5 Streams merge result : ");
final5StreamsMergeREsult.forEach(merge -> System.out.println(merge));
}
}
5 Streams merge result : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
8. Example 5 To Merge Multiple Streams using flatMap() method
import java.util.stream.Stream;
public class MultipleStreamMergeFlatMapExample {
public static void main(String[] args) {
// Creating stream 1
Stream<Integer> stream1 = Stream.of(1, 2, 3);
// Creating stream 2
Stream<Integer> stream2 = Stream.of(4, 5, 6);
// Creating stream 3
Stream<Integer> stream3 = Stream.of(7, 8, 9);
// Creating stream 4
Stream<Integer> stream4 = Stream.of(10, 11, 12);
// Creating stream 5
Stream<Integer> stream5 = Stream.of(13, 14, 15);
// Creating a new string from all 5 streams using Stream.of() method.
Stream<Stream<Integer>> finalStream = Stream.of(stream1, stream2, stream3, stream4, stream5);
Stream<Integer> mergedStream = finalStream.flatMap(stream -> stream.map( v -> v));
// printing sorted merged stream values
System.out.println("merge with flatmap : ");
mergedStream.forEach(merge -> System.out.println(merge));
}
}
5 Streams merge result : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
9. Example 6 To Merge Streams and Retain Unique Objects
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class RetainDistinctValues {
public static void main(String[] args) {
// Creating stream 1
Stream<Integer> stream1 = Stream.of(1, 2, 3);
// Creating stream 2
Stream<Integer> stream2 = Stream.of(1, 2, 3, 4, 5, 6);
// Removing duplicate elemetns
List<Integer> uniqueValues = Stream.concat(stream1, stream2).distinct().collect(Collectors.toList());
// printing sorted merged stream values
System.out.println("Removed duplicates after merge");
uniqueValues.forEach(merge -> System.out.println(merge));
}
}
Removed duplicates after merge 1 2 3 4 5 6
10. Example 7 To Merge Streams with Custom Objects
import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; public class CusomObjectsDistinctValues { public static void main(String[] args) { // Create Employee stream 1 Stream<Employee> stream1 = getEmployeStream1(); // Create Employee stream 2 Stream<Employee> stream2 = getEmployeStream2(); // Removing duplicate elemetns List<Employee> uniqueValues = Stream.concat(stream1, stream2).filter(distinctByKey(Employee::getId)).collect(Collectors.toList()); // printing sorted merged stream values System.out.println("Removed duplicates after merge"); uniqueValues.forEach(merge -> System.out.println(merge)); } public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) { Map<Object, Boolean> map = new ConcurrentHashMap<>(); return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null; } private static Stream<Employee> getEmployeStream1() { Employee e1 = new Employee(100, "Navamsha"); Employee e2 = new Employee(101, "dhsamsha"); Employee e3 = new Employee(103, "Chitra"); return Stream.of(e1, e2, e3); } private static Stream<Employee> getEmployeStream2() { Employee e1 = new Employee(100, "Navamsha"); Employee e2 = new Employee(101, "dhsamsha"); Employee e3 = new Employee(102, "Varshad"); Employee e4 = new Employee(103, "Chitra"); return Stream.of(e1, e2, e3, e4); } } class Employee { private int id; private String name; public Employee(int id, String name) { super(); this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Employee [id=" + id + ", name=" + name + "]"; } }
Removed duplicates after merge Employee [id=100, name=Navamsha] Employee [id=101, name=dhsamsha] Employee [id=103, name=Chitra] Employee [id=102, name=Varshad]
11. Example 8 concat() with stream has already been operated upon or closed
import java.util.stream.Stream;
public class StreamConcatException {
public static void main(String[] args) {
// Creating stream 1
Stream<Integer> stream1 = Stream.of(1, 1, 1);
// Creating stream 2
Stream<Integer> stream2 = Stream.of(2, 2, 2);
// Merging two streams in java 8 using concat() method
Stream<Integer> resultStream = Stream.concat(stream1, stream2);
// printing stream1 values
System.out.println("Stream 1 values are ");
stream1.forEach(even -> System.out.println(even));
}
}
Stream 1 values are Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed at java.util.stream.AbstractPipeline.sourceStageSpliterator(AbstractPipeline.java:279) at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580) at limit.StreamJoinTwoStreams.main(StreamJoinTwoStreams.java:21)
Observe output saying stream1 is already closed and you can not make any stream operations on it.
But, we did not call any terminal operation to close the stream. We have just called the concat() method. concat() method closes the passed two streams internally by calling Stream.onClose(Streams.composedClose(a, b)) method.
12. Conclusion
In this article, You've seen in-depth about the Stream.concat() method.
And also shown how to merge two or more streams using concat() and flatMap() methods.
All examples are shown are over GitHub.
No comments:
Post a Comment
Please do not add any spam links in the comments section.