0% found this document useful (0 votes)
27 views

Stream_java

Uploaded by

prernajangra1124
Copyright
© © All Rights Reserved
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
27 views

Stream_java

Uploaded by

prernajangra1124
Copyright
© © All Rights Reserved
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 6

STREAM

- when we have multiple threads then its better to have the immutable
data which means we do not change the values then here we can use
streams
- streams are related to collection Framework (group of objects)
- these streams are very different from io stream (sequence of data) :
with help of this we read or write the data from source to destination
- streams reduce the code length .
What are Streams in Java?
Streams in Java are a new abstraction introduced in Java 8 that represents a sequence
of elements. They provide a way to process collections of data in a declarative and
functional programming style.
Key Concepts of Streams:
1. Sequence of Elements: Streams represent a sequence of elements of a specific
type. They are not data structures themselves but are abstractions to perform
computations on the data.

2. Source: A stream is created from a data source, such as a collection, array, or I/O
channel. The source provides the data for the stream to process.

3. Pipelines: Stream operations are chained together to form a pipeline. Pipelines


consist of a source, zero or more intermediate operations, and a terminal operation.
4. Intermediate Operations: These are operations that transform a stream into
another stream. Examples include filter, map, and sorted. Intermediate operations
are lazy, meaning they are not executed until a terminal operation is invoked.
5. Terminal Operations: These operations produce a result or a side-effect and mark
the end of the stream pipeline. Examples include forEach, collect, and reduce.
Once a terminal operation is invoked, the stream is considered consumed and cannot
be used further.
6. Lazy Evaluation: Streams are lazy; intermediate operations are not executed until
a terminal operation is invoked. This allows for optimization and efficient processing
of large data sets.

Why Use Streams?


1. Concise and Readable Code: Streams allow for writing more readable and concise
code. Operations like filtering, mapping, and reducing can be expressed in a clear,
functional style.

2. Parallel Processing: Streams support parallel operations, making it easier to


perform bulk operations on large datasets efficiently by leveraging multiple processor
cores.
3. Immutable Processing: Stream operations do not modify the underlying data
source. Instead, they create new streams with the transformed data, promoting
immutability and thread-safety.

Example of Stream Usage:


Consider a simple example where we have a list of strings, and we want to filter out
the strings that start with the letter "a", convert them to uppercase, and collect the
result into a list.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class StreamExample {


public static void main(String[] args) {
List<String> strings = Arrays.asList("apple", "banana", "avocado", "cherry", "apricot");

List<String> result = strings.stream() // Create a stream from the list


.filter(s -> s.startsWith("a")) // Filter strings that start with "a"
.map(String::toUpperCase) // Convert each string to uppercase
.collect(Collectors.toList()); // Collect the result into a list

System.out.println(result); // Output: [APPLE, AVOCADO, APRICOT]


}
}

In this example:
 stream() creates a stream from the list of strings.
 filter(s -> s.startsWith("a")) is an intermediate operation that filters the
stream to include only elements that start with "a".
 map(String::toUpperCase) is another intermediate operation that transforms each
element of the stream to uppercase.
 collect(Collectors.toList()) is a terminal operation that collects the elements
of the stream into a new list.

Types of Streams:
1. Stream<T>: The most general stream interface.
2. IntStream, LongStream, DoubleStream: Specializations for primitive types (int, long, double)
to avoid boxing overhead.

Common Stream Operations:


 Creation: Creating streams from collections, arrays, or specific methods (Stream.of,
Stream.generate).
 Filtering: Using filter to select elements based on a predicate.
 Mapping: Using map and flatMap to transform elements.
 Reduction: Using reduce, collect, and other methods to aggregate stream elements.
 Sorting: Using sorted to sort elements.
 Matching: Using anyMatch, allMatch, noneMatch to check conditions on elements.
 Iteration: Using forEach to perform actions on each element.

Streams offer a powerful and flexible way to process data in Java, enabling more
readable, maintainable, and efficient code.
Theory Questions
Question 1: What is a stream in Java?
Answer: A stream in Java is a sequence of elements supporting sequential and
parallel aggregate operations. It provides a functional approach to processing
collections of objects and does not store elements but rather computes them on
demand.
Question 2: What are the differences between a collection
and a stream?
Answer:
 Storage: Collections store data, while streams do not store elements and are computed on
demand.
 Processing: Streams are designed for functional-style operations (map, filter, reduce),
whereas collections are designed for storing and manipulating data.
 Laziness: Streams support lazy evaluation, meaning intermediate operations are not
executed until a terminal operation is invoked.
 Traversal: Streams can be traversed only once, while collections can be traversed multiple
times.

Question 3: What are intermediate and terminal operations


in a stream?
Answer:
 Intermediate Operations: These operations transform a stream into another stream and are
lazy. Examples include filter, map, flatMap, sorted, and distinct.
 Terminal Operations: These operations produce a result or a side-effect and mark the end of
the stream pipeline. Examples include forEach, collect, reduce, count,
findFirst, and anyMatch.

Question 4: Explain the concept of lazy evaluation in


streams.
Answer: Lazy evaluation in streams means that intermediate operations are not
executed until a terminal operation is invoked. This allows for efficient processing as
operations are performed only when necessary and can optimize the execution
pipeline.
Question 5: What is the difference between map and flatMap?
Answer:
 map: Transforms each element of the stream into another object, potentially changing the
type of the elements.
 flatMap: Flattens the resulting streams of a mapping function into a single stream. It is
used when each element produces multiple elements and you want to flatten them into a
single continuous stream.

Practical Questions
Question 1: Write a stream operation to filter a list of
integers to get only even numbers.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class EvenNumbers {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

List<Integer> evenNumbers = numbers.stream()


.filter(n -> n % 2 == 0)
.collect(Collectors.toList());

System.out.println(evenNumbers); // Output: [2, 4, 6, 8, 10]


}
}
Question 2: How do you create a stream from an array?
import java.util.Arrays;
import java.util.stream.Stream;

public class ArrayStream {


public static void main(String[] args) {
String[] array = {"a", "b", "c"};
Stream<String> stream1 = Arrays.stream(array);
Stream<String> stream2 = Stream.of(array);

stream1.forEach(System.out::println); // Output: a, b, c
stream2.forEach(System.out::println); // Output: a, b, c
}
}

Question 3: Write a stream operation to convert a list of


strings to uppercase.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class ToUpperCase {


public static void main(String[] args) {
List<String> words = Arrays.asList("apple", "banana", "cherry");

List<String> upperCaseWords = words.stream()


.map(String::toUpperCase)
.collect(Collectors.toList());

System.out.println(upperCaseWords); // Output: [APPLE, BANANA, CHERRY]


}
}

Question 4: How do you handle exceptions in a stream


operation?
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class ExceptionHandling {


public static void main(String[] args) {
List<String> list = Arrays.asList("10", "20", "invalid", "30");

List<Integer> numbers = list.stream()


.map(ExceptionHandling::safeParseInt)
.filter(i -> i.isPresent())
.map(i -> i.get())
.collect(Collectors.toList());

System.out.println(numbers); // Output: [10, 20, 30]


}

private static Optional<Integer> safeParseInt(String s) {


try {
return Optional.of(Integer.parseInt(s));
} catch (NumberFormatException e) {
return Optional.empty();
}
}
}

Question 5: Write a stream operation to find the maximum


value in a list of integers.
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

public class MaxValue {


public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(3, 5, 9, 1, 6);

Optional<Integer> max = numbers.stream()


.max(Integer::compareTo);

max.ifPresent(System.out::println); // Output: 9
}
}

Question 6: Demonstrate how to create a parallel stream and


use it to sum a list of integers.
import java.util.Arrays;
import java.util.List;

public class ParallelStreamSum {


public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

int sum = numbers.parallelStream()


.mapToInt(Integer::intValue)
.sum();

System.out.println(sum); // Output: 55
}
}
Combination of Theory and Practical
Question 1: Explain the use of Collectors.toMap() with an
example.
Answer: Collectors.toMap() is used to collect elements of a stream into a Map. It
requires two functions: one for the key and one for the value.
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class CollectorsToMap {


public static void main(String[] args) {
List<String> words = Arrays.asList("apple", "banana", "cherry");

Map<String, Integer> wordLengthMap = words.stream()


.collect(Collectors.toMap(word -> word, String::length));

System.out.println(wordLengthMap);
// Output: {apple=5, banana=6, cherry=6}
}
}

Question 2: What is the purpose of flatMap and provide an


example use case.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class FlatMapExample {


public static void main(String[] args) {
List<List<String>> listOfLists = Arrays.asList(
Arrays.asList("a", "b", "c"),
Arrays.asList("d", "e", "f"),
Arrays.asList("g", "h", "i")
);

List<String> flatList = listOfLists.stream()


.flatMap(List::stream)
.collect(Collectors.toList());

System.out.println(flatList); // Output: [a, b, c, d, e, f, g, h, i]


}
}

You might also like