blog

Home / DeveloperSection / Blogs / Explain the Stream API introduced in Java 8. How does it work?

Explain the Stream API introduced in Java 8. How does it work?

Explain the Stream API introduced in Java 8. How does it work?

Ravi Vishwakarma 260 19-Jul-2024

The Stream API, introduced in Java 8, is a powerful feature that allows for functional-style operations on collections of data. It enables developers to write more concise, readable, and expressive code for processing sequences of elements. The Stream API is designed to work with data sources such as collections, arrays, and I/O channels.

Stream API in Java 8 provides a powerful and flexible way to work with sequences of data. It simplifies many common operations on collections, improves readability, and allows for more expressive and functional programming styles.

Key Concepts

Stream:

  • A stream is a sequence of elements supporting sequential and parallel aggregate operations.
  • Streams do not store data; they operate on the data stored in collections.
  • Streams are lazy; computations on the data are only performed when necessary.

Pipeline:

  • A stream pipeline consists of a source (e.g., a collection), zero or more intermediate operations, and a terminal operation.
  • Intermediate operations are lazy and return a new stream, while terminal operations are eager and produce a result or side effect.

Intermediate Operations:

  • Operations that transform a stream into another stream. They are lazy, meaning they are not executed until a terminal operation is invoked.
  • Examples: filter(), map(), sorted(), distinct(), limit(), skip()
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
Stream<String> stream = names.stream().filter(name -> name.startsWith("A"));

Terminal Operations:

  • Operations that produce a result or a side effect and mark the end of the stream pipeline.
  • Examples: forEach(), collect(), reduce(), count(), findFirst(), allMatch()
long count = names.stream().filter(name -> name.startsWith("A")).count();

 

Working with Streams

Creating Streams

// From a collection
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> streamFromList = list.stream();

// From an array
String[] array = {"a", "b", "c"};
Stream<String> streamFromArray = Arrays.stream(array);

// From individual values
Stream<String> streamOfValues = Stream.of("a", "b", "c");

// From a file
Stream<String> lines = Files.lines(Paths.get("file.txt"));

Intermediate Operations

Intermediate operations transform a stream into another stream:

List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");

// Filtering
Stream<String> filtered = names.stream().filter(name -> name.startsWith("A"));

// Mapping
Stream<Integer> nameLengths = names.stream().map(String::length);

// Sorting
Stream<String> sorted = names.stream().sorted();

// Chaining operations
Stream<String> processed = names.stream()
                                .filter(name -> name.length() > 3)
                                .map(String::toUpperCase)
                                .sorted();

Terminal Operations

Terminal operations produce a result or side effect:

List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");

// Collecting to a list
List<String> filteredNames = names.stream()
                                  .filter(name -> name.startsWith("A"))
                                  .collect(Collectors.toList());

// Counting elements
long count = names.stream()
                  .filter(name -> name.length() > 3)
                  .count();

// Reducing to a single value
Optional<String> concatenated = names.stream()
                                     .reduce((name1, name2) -> name1 + ", " + name2);

// Iterating over elements
names.stream()
     .forEach(System.out::println);

 

Benefits of the Stream API

Concise and Readable Code: Stream operations are typically more readable and concise than traditional loops.

Declarative Programming: Streams allow for a more declarative style of programming, specifying what to do rather than how to do it.

Parallel Processing: Streams can be easily parallelized, making it simple to leverage multi-core processors for performance gains.

List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
long count = names.parallelStream()
                  .filter(name -> name.startsWith("A"))
                  .count();

Lazy Evaluation: Intermediate operations are not executed until a terminal operation is invoked, which can lead to performance optimizations.

 


Updated 19-Jul-2024
Hi, my self Ravi Vishwakarma. I have completed my studies at SPICBB Varanasi. now I completed MCA with 76% form Veer Bahadur Singh Purvanchal University Jaunpur. SWE @ MindStick | Software Engineer | Web Developer | .Net Developer | Web Developer | Backend Engineer | .NET Core Developer

Leave Comment

Comments

Liked By