Java 8 | Stream Interview Questions
In this article, we are going to cover some favorite interview questions of every interviewer on the newer concept, Stream, which is one of the major updates in the Java 8 release. Now, let's straight start with the questions.
1. What is Stream in Java 8?
Stream is a concept where we can create a stream of objects from a collection. We have java.util.Stream package in Java 8 where we have all the Stream Interfaces/Classes/Enums. We should be aware of all the interfaces/classes/enums but with time we all learn. Some of the frequent being used are shown below-
- Stream<T>- This is an interface that represents a set of items that allows for both sequential and parallel aggregate operations.
- Collectors- This is a class that is an implementation of Collector(another interface) that does a variety of helpful reduction actions, such as grouping elements into collections, summarising elements based on various criteria, and so on.
Streams can be obtained by a variety of methods. Here are a few examples:
- Using the stream() and parallelStream() methods on a Collection.
- Using Arrays.stream(Object[]) from an array.
- Stream.of(Object[]), IntStream.range(int, int), or Stream.iterate(Object, UnaryOperator) are static factory methods on the stream classes.
- BufferedReader.lines() can be used to get the lines of a file.
- Methods in Files can be used to get streams of file paths.
- Random.ints() can be used to get streams of random numbers.
- BitSet.stream(), Pattern.splitAsStream(java.lang.CharSequence), and JarFile.stream are among the other stream-bearing methods in the JDK ().
2. What are the types of operations available?
There are only two types of operations, i.e., intermediate and terminary. Stream is always referred to as lazy because of the intermediate operations available. Here is new terminology for you, Stream Pipeline which can be obtained by combining these 2 operations. Now, let's understand both these operations in detail.
- Intermediate Operations- A fresh stream is returned by intermediate operations. They're always lazy; doing an intermediate operation like filter() doesn't actually filter anything; instead, it creates a new stream that contains the items of the original stream that fit the provided predicate when browsed.
The source of the pipeline is not traversed until the pipeline's terminal operation is completed. - Terminal Operations- Stream.forEach and IntStream.sum are examples of terminal operations that traverse the stream to create a result or a side-effect. The stream pipeline is regarded as consumed once the terminal action is completed, and it can no longer be used; if you need to traverse the same data source again, you must return to the data source to obtain a new stream.
Terminal operations are usually always eager, completing their traverse of the data source and pipeline processing before returning. Only the terminal operations iterator() and spliterator() aren't; they're included as an "escape hatch" to allow arbitrary client-controlled pipeline traversals if the current operations aren't up to the task.
3. What are the benefits of Streams being lazy?
When we say that Stream is lazy, we mean that most of the methods in class java.util.stream.Stream are lazy, meaning that they will not work if they are simply added to the Stream pipeline. They only work when you call a terminal method on the Stream, and they finish as soon as they locate the data they're seeking instead of scanning the entire set of data.
When performing operations such as "find the first string longer than 1000 characters," laziness allows for avoiding examining all of the data when it is not required; for example, "find the first string longer than 1000 characters," it is only necessary to examine a small number of strings to find one that meets the criteria without examining all of the strings available from the source. (When the input stream is infinite rather than just large, this behavior becomes considerably more relevant.)
4. Difference between Intermediate and Terminal operations?
Intermediate operations are those that return Stream, allowing for other operations on a stream to be performed. These actions are always lazily executed, meaning they do not process the stream at the call site. Only when a terminal operation is present may an intermediate operation process data. Filter, map, and flatMap are examples of intermediate processes.
Terminal activities, on the other hand, end the pipeline and begin stream processing. During a terminal operation call, the stream is sent through all intermediate operations. forEach, reduce, Collect, and sum are examples of terminal operations.
5. Dfference between map() and flatMap() operation?
The return value of a map operation is wrapped inside its ordinal type, whereas the return value of flatMap is not. A map operation in Optional, for example, returns OptionalString> type, whereas flatMap returns String type.
So, after mapping, we must flatten the object in order to extract the value, whereas, after flat mapping, we do not need to do so because the object is already flattened. In Stream, we use the same notion for mapping and flat mapping.
Both map and flatMap are intermediate stream operations that take a function and apply it to all of a stream's elements. The difference is that while this function returns a value for the map, it returns a stream for flatMap. The flatMap operation combines the streams into a single stream.
6. What are the types of Intermediate operations? Or Difference between Stateful vs Stateless operations?
The stream's intermediate operations are divided into two categories: stateless and stateful. Each element is processed independently of the others in a stateless procedure. The processing of one element in a stateful operation may be influenced by the processing of other components.
A stateful operation is one whose outcome is dependent on any state that may change throughout the pipeline's execution. During the execution of the pipeline, stateless activities do not keep any state.
Stream supports a number of intermediate operations, all of which are stateful by definition. To complete the operation, they keep some internal state.
distinct(), sorted(), limit(), and skip() are the intermediary operations, remaining operations are stateless. When processing the current element, these stateful intermediate operations use states from previously processed items.
The sorted() method returns a stream that has the invoking stream's contents arranged in the natural order. Because the order of one element is determined by the values of the other elements, sorting is a stateful operation.
Filtering elements based on a stateless predicate, on the other hand, is stateless because each element is processed separately. Filter() can (and should) be stateless as a result.
Stream Practical Interview Questions
Our employee class looks like shown below-
public class Employee { private Long id; private String name; private String email; private Integer age; private Integer salary;
// constructor
// getters and setters
1. Given a list of employee objects, print the salaries of all employees using Stream.
List<Employee> employeeList = new ArrayList<>(); employeeList.stream().forEach(emp -> System.out.println(emp.getSalary()));
2. Given a list of employee objects, print the names of all employees starting with 'P' using Stream.
employeeList.stream() .filter(emp -> emp.getName().startsWith("P")) .forEach(emp -> System.out.println(emp.getName()));
No comments:
Post a Comment