Introduction
Java 8 introduced the Stream API, used for processing sequences of elements in a functional and declarative manner. When working with streams, there may be scenarios where you need to merge multiple streams into a single stream. This could be useful, for example, when you have several collections or arrays and want to process them as a single stream.
In this guide, we’ll explore how to merge multiple streams in Java 8. We will demonstrate how to merge streams of different types, including streams of integers, strings, and custom objects, and provide examples to illustrate each approach.
Table of Contents
- Problem Statement
- Solution Steps
- Java Program
- Merging Two Streams of Integers
- Merging Two Streams of Strings
- Merging Multiple Streams Using
Stream.concat() - Merging Streams of Custom Objects
- Advanced Considerations
- Conclusion
Problem Statement
The task is to create a Java program that:
- Demonstrates how to merge two or more streams into a single stream.
- Applies this merging technique to different types of data, including integers, strings, and custom objects.
- Outputs the merged stream for further processing or display.
Example 1:
- Input: Two lists of integers
[1, 2, 3]and[4, 5, 6] - Output: Merged stream
[1, 2, 3, 4, 5, 6]
Example 2:
- Input: Three lists of strings
["apple"],["banana"],["cherry"] - Output: Merged stream
["apple", "banana", "cherry"]
Solution Steps
- Create Streams: Start with individual streams of elements.
- Merge the Streams: Use methods such as
Stream.concat()orStream.of()to combine multiple streams into a single stream. - Process or Display the Merged Stream: Print or further process the elements of the merged stream.
Java Program
Merging Two Streams of Integers
The Stream.concat() method can be used to merge two streams into a single stream.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Java 8 - Merging Two Streams of Integers
* Author: https://www.rameshfadatare.com/
*/
public class MergeIntegerStreams {
public static void main(String[] args) {
// Step 1: Create two lists of integers
List<Integer> list1 = Arrays.asList(1, 2, 3);
List<Integer> list2 = Arrays.asList(4, 5, 6);
// Step 2: Create streams from the lists
Stream<Integer> stream1 = list1.stream();
Stream<Integer> stream2 = list2.stream();
// Step 3: Merge the two streams
Stream<Integer> mergedStream = Stream.concat(stream1, stream2);
// Step 4: Collect and display the merged stream
List<Integer> mergedList = mergedStream.collect(Collectors.toList());
System.out.println("Merged Stream: " + mergedList);
}
}
Output
Merged Stream: [1, 2, 3, 4, 5, 6]
Explanation
- The
Stream.concat(stream1, stream2)method merges the two streams into a single stream. - The
collect(Collectors.toList())method collects the merged stream elements into a list.
Merging Two Streams of Strings
You can also use Stream.concat() to merge streams of strings.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Java 8 - Merging Two Streams of Strings
* Author: https://www.rameshfadatare.com/
*/
public class MergeStringStreams {
public static void main(String[] args) {
// Step 1: Create two lists of strings
List<String> list1 = Arrays.asList("apple", "banana");
List<String> list2 = Arrays.asList("cherry", "date");
// Step 2: Create streams from the lists
Stream<String> stream1 = list1.stream();
Stream<String> stream2 = list2.stream();
// Step 3: Merge the two streams
Stream<String> mergedStream = Stream.concat(stream1, stream2);
// Step 4: Collect and display the merged stream
List<String> mergedList = mergedStream.collect(Collectors.toList());
System.out.println("Merged Stream: " + mergedList);
}
}
Output
Merged Stream: [apple, banana, cherry, date]
Explanation
- The
Stream.concat(stream1, stream2)method merges the two streams into a single stream. - The
collect(Collectors.toList())method collects the merged stream elements into a list.
Merging Multiple Streams Using Stream.of()
When you need to merge more than two streams, Stream.of() combined with flatMap() can be a more flexible solution.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Java 8 - Merging Multiple Streams Using Stream.of() and flatMap()
* Author: https://www.rameshfadatare.com/
*/
public class MergeMultipleStreams {
public static void main(String[] args) {
// Step 1: Create three lists of strings
List<String> list1 = Arrays.asList("apple");
List<String> list2 = Arrays.asList("banana");
List<String> list3 = Arrays.asList("cherry");
// Step 2: Create streams from the lists
Stream<String> stream1 = list1.stream();
Stream<String> stream2 = list2.stream();
Stream<String> stream3 = list3.stream();
// Step 3: Merge the streams using Stream.of() and flatMap()
Stream<String> mergedStream = Stream.of(stream1, stream2, stream3)
.flatMap(s -> s);
// Step 4: Collect and display the merged stream
List<String> mergedList = mergedStream.collect(Collectors.toList());
System.out.println("Merged Stream: " + mergedList);
}
}
Output
Merged Stream: [apple, banana, cherry]
Explanation
- The
Stream.of(stream1, stream2, stream3)method creates a stream of streams. - The
flatMap(s -> s)method flattens the stream of streams into a single stream. - The
collect(Collectors.toList())method collects the merged stream elements into a list.
Merging Streams of Custom Objects
You can merge streams of custom objects using the same approach, ensuring that all objects from the merged streams are processed together.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Java 8 - Merging Streams of Custom Objects
* Author: https://www.rameshfadatare.com/
*/
public class MergeCustomObjectStreams {
public static void main(String[] args) {
// Step 1: Create two lists of products
List<Product> list1 = Arrays.asList(new Product("Laptop", 1500));
List<Product> list2 = Arrays.asList(new Product("Phone", 800), new Product("Tablet", 600));
// Step 2: Create streams from the lists
Stream<Product> stream1 = list1.stream();
Stream<Product> stream2 = list2.stream();
// Step 3: Merge the two streams
Stream<Product> mergedStream = Stream.concat(stream1, stream2);
// Step 4: Collect and display the merged stream
List<Product> mergedList = mergedStream.collect(Collectors.toList());
mergedList.forEach(product ->
System.out.println("Product: " + product.getName() + ", Price: " + product.getPrice()));
}
}
// Custom class Product
class Product {
private String name;
private double price;
public Product(String name, double price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
}
Output
Product: Laptop, Price: 1500.0
Product: Phone, Price: 800.0
Product: Tablet, Price: 600.0
Explanation
- The
Stream.concat(stream1, stream2)method merges the two streams into a single stream of custom objects. - The merged stream is then collected into a list, and the details of each product are displayed.
Advanced Considerations
-
Handling Large Streams: When merging large streams, consider the memory footprint and performance. Use parallel streams if the merged stream is processed in a parallelizable manner.
-
Stream Order: The order of elements in the merged stream is determined by the order of the original streams. If maintaining order is crucial, ensure that streams are merged in the correct sequence.
-
Immutable Streams: Once merged, streams are immutable. Any modification should be performed on a collected list or another suitable data structure.
Conclusion
This guide provides methods for merging multiple streams in Java 8, covering different types of data, including integers, strings, and custom objects. Merging streams is a powerful technique that allows you to process data from multiple sources as a single, cohesive stream. By understanding how to merge streams effectively, you can simplify your data processing tasks and create more flexible and efficient Java applications.