Learn to use Stream.concat() method is used to merge two streams into one stream which consist of all elements of both merged streams.
1. Stream concat() method
static <T> Stream<T> concat(Stream<? extends T> firstStream, Stream<? extends T> secondStream)
- This method creates a lazily concatenated stream whose elements are all the elements of the firstStream followed by all the elements of the secondStream.
- The resulting stream is ordered if both of the input streams are ordered.
- The resulting stream is parallel if either of the input streams is parallel.
- When the resulting stream is closed, the close handlers for both input streams are invoked.
2. Merge two streams
Java example to merge two streams of numbers – to obtain an stream which contains numbers from both streams.
import java.util.stream.Stream; public class Main { public static void main(String[] args) { Stream<Integer> firstStream = Stream.of(1, 2, 3); Stream<Integer> secondStream = Stream.of(4, 5, 6); Stream<Integer> resultingStream = Stream.concat(firstStream, secondStream); System.out.println( resultingStream.collect(Collectors.toList()) ); } }
Program Output.
[1, 2, 3, 4, 5, 6]
3. Merge multiple streams
Java example to merge four streams of numbers – to obtain an stream which contains numbers from all streams. Notice we have made a static import to Stream.concat() function which makes the code readable.
import java.util.stream.Collectors; import java.util.stream.Stream; import static java.util.stream.Stream.*; public class Main { public static void main(String[] args) { Stream<Integer> first = Stream.of(1, 2); Stream<Integer> second = Stream.of(3,4); Stream<Integer> third = Stream.of(5, 6); Stream<Integer> fourth = Stream.of(7,8); Stream<Integer> resultingStream = Stream.concat(first, concat(second, concat(third, fourth))); System.out.println( resultingStream.collect(Collectors.toList()) ); } }
Program Output.
[1, 2, 3, 4, 5, 6, 7, 8]
4. Java merge streams and retain unique elements
4.1. Numbers and strings
While merging two streams, we can use distinct() API and resulting stream will contain only unique elements.
import java.util.stream.Collectors; import java.util.stream.Stream; public class Main { public static void main(String[] args) { Stream<Integer> firstStream = Stream.of(1, 2, 3, 4, 5, 6); Stream<Integer> secondStream = Stream.of(4, 5, 6, 7, 8, 9); Stream<Integer> resultingStream = Stream.concat(firstStream, secondStream) .distinct(); System.out.println( resultingStream.collect(Collectors.toList()) ); } }
Program Output.
[1, 2, 3, 4, 5, 6, 7, 8, 9]
4.2. Custom objects
In case of merging streams of custom objects, we can drop the duplicate elements during stream iteration. We can use the distinctByKey() function created for java stream distinct by object property example.
import java.util.ArrayList; 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 Main { public static void main(String[] args) { Stream<Employee> stream1 = getEmployeeListOne().stream(); Stream<Employee> stream2 = getEmployeeListTwo().stream(); Stream<Employee> resultingStream = Stream.concat(stream1, stream2) .filter(distinctByKey(Employee::getFirstName)); System.out.println( resultingStream.collect(Collectors.toList()) ); } 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 ArrayList<Employee> getEmployeeListOne() { ArrayList<Employee> list = new ArrayList<>(); list.add( new Employee(1l, "Lokesh", "Gupta") ); list.add( new Employee(5l, "Brian", "Piper") ); list.add( new Employee(7l, "Charles", "Piper") ); list.add( new Employee(6l, "David", "Beckham") ); return list; } private static ArrayList<Employee> getEmployeeListTwo() { ArrayList<Employee> list = new ArrayList<>(); list.add( new Employee(2l, "Lokesh", "Gupta") ); list.add( new Employee(4l, "Brian", "Piper") ); list.add( new Employee(3l, "David", "Beckham") ); return list; } }
Program Output.
[ Employee [id=1, firstName=Lokesh, lastName=Gupta], Employee [id=5, firstName=Brian, lastName=Piper], Employee [id=7, firstName=Charles, lastName=Piper], Employee [id=6, firstName=David, lastName=Beckham]]
Drop me your questions in comments section related to merging two or more streams of objects in Java 8.
Happy Learning !!
Reference:
Comments