Java 8 Streams With Examples

Learn Java 8 Stream With Examples

Last Updated on December 31, 2024

TL;DR: Java 8 Stream API simplifies data processing with functional-style operations. It enables efficient filtering, mapping, and aggregation of collections through methods like filter(), map(), reduce(), collect(), and forEach(). Streams are lazy, immutable, and support parallel processing, making them powerful for large-scale data operations.

Java Streams is a powerful feature introduced in Java 8 that allows for functional-style operations on collections of elements. Java 8 streams provide a concise and expressive way to filter, transform, and aggregate data in Java. With Java streams, you can perform complex operations on data with just a few lines of code, making your code more readable and maintainable. Java 8 Streams are designed to be parallelizable, which means they can take advantage of multiple cores in a computer to process data faster.

In this guide, we will explore the basics of Java 8 Streams, including how to create them, manipulate them, and use them effectively in your code.

  • Lazy Evaluation: Operations are not executed until a terminal operation is invoked.
  • Immutable: Streams do not modify the original data source.
  • Pipelined Processing: Operations are chained in a pipeline.
  • Parallel Processing: Supports parallel execution using parallelStream().

Intermediate Operations

These operations transform or filter the stream. They are lazy and only execute when a terminal operation is invoked.

filter(Predicate): Filters elements based on a condition

map(Function): Transforms each element.

sorted(Comparator): Sorts elements.

distinct(): Removes duplicate elements.

limit(long n): Limits the stream to n elements.

Terminal Operations

These operations trigger the stream pipeline execution and produce a result or side-effect. After a terminal operation, the stream can no longer be used.

forEach(Consumer): Performs an action on each element

collect(Collector): Collects results into a structure (e.g., List, Set)

reduce(BinaryOperator): Aggregates elements into a single result.

anyMatch / allMatch / noneMatch: Validates conditions.

Short-Circuiting Operations

Some terminal operations can short-circuit, meaning they stop processing as soon as a condition is met.

anyMatch, allMatch, noneMatch

findFirst, findAny

List<String> words = Arrays.asList("Java", "Streams", "are", "powerful", "and", "easy", "to", "use");
List<String> filteredWords = words.stream()
    .filter(w -> w.length() > 4) // filter out words with less than 4 characters
    .map(String::toUpperCase) // convert the words to upper case
    .collect(Collectors.toList()); // collect the result in a list

System.out.println(filteredWords); // ["STREAMS", "POWERFUL", "EASY"]

In this example, we first create a list of strings “words”, then we use the stream() method to create a stream of the words in the list. Then we use the filter() method to filter the stream to only include words with more than 4 characters and use map() method to convert the words to upper case and collect the results in a list.

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
int sum = numbers.stream().reduce(0, Integer::sum);
System.out.println(sum); // 55

In this example, we first create a list of integers “numbers”, then we use the stream() method to create a stream of the integers in the list. Then we use the reduce() method to perform a reduction operation on the elements in the stream by adding them up and printing the result.

List<Integer> numbersList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

int sumOfEvenNumbers = numbersList.stream()
                                  .filter(number -> number % 2 == 0)
                                  .mapToInt(Integer::intValue)
                                  .sum();

System.out.println("Sum of even numbers: " + sumOfEvenNumbers);

Assume the list “numbersList” is already initialized with some integer values, then we use the filter() method to filter the even numbers. Then we use the mapToInt() method to convert the Integers into int values and finally perform a sum operation on the even numbers and printing the result.

List<String> namesList = Arrays.asList("Alice", "Alex", "Bob", "Amy", "Andrew", "Amanda", "David");

long count = namesList.stream()
                      .filter(name -> name.startsWith("A") && name.length() > 5)
                      .count();

System.out.println("Count of names starting with 'A' and length > 5: " + count);

Consider a list of strings called “namesList”. Here we have to write a Java 8 stream expression to find the count of names that start with the letter “A” and have a length greater than 5.

We have used the “filter” and “count” methods provided by the Stream API, along with string manipulation methods like “startsWith” and “length” to achieve the expected result.

List<Person> people = Arrays.asList(
    new Person("John", 25),
    new Person("Jane", 30),
    new Person("Bob", 20)
);
List<Person> sorted = people.stream()
    .sorted(Comparator.comparing(Person::getAge))
    .collect(Collectors.toList());
System.out.println(sorted);

In this example, we first create a list of Person objects and then use the stream() method to create a stream of people. Then we use the sorted() method to sort the stream by age and collect the result in a list.

List<Person> people = Arrays.asList(
    new Person("John", 25, "male"),
    new Person("Jane", 30, "female"),
    new Person("Bob", 20, "male")
);
Map<String, List<Person>> groupedByGender = people.stream()
    .collect(Collectors.groupingBy(Person::getGender));
System.out.println(groupedByGender);

In this example, we first create a list of Person objects and then use the stream() method to create a stream of people. Then we use the collect() method with the groupingBy() collector to group the elements in the stream by the gender attribute of the Person object. The result is a Map where the keys are the different gender values and the values are lists of Person objects with that gender.

These are just a few examples of how the Java 8 Streams API can be used to perform various operations on collections of data in a functional way. The Java 8 Streams API provides a powerful and expressive way to process data, making it easier to write readable, maintainable and efficient code.

Published on January 24, 2023

Last updated on December 31, 2024

Share:

Leave A Reply

Your email address will not be published. Required fields are marked *

You May Also Like

Discover the fascinating world of Java and unleash its powerful features that make it a beloved programming language.
Java 8 introduced several new features, including lambda expressions, functional interfaces, streams, and more. These features improved the language's expressiveness...