How to filter a collection using Stream API in Java

JavaJavaBeginner
Practice Now

Introduction

The Java Stream API provides a powerful and versatile way to work with collections of data. In this tutorial, we will explore how to leverage the Stream API to filter collections, allowing you to efficiently extract the data you need. Whether you're a Java beginner or an experienced developer, this guide will equip you with the knowledge and skills to streamline your data processing tasks.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL java(("`Java`")) -.-> java/FileandIOManagementGroup(["`File and I/O Management`"]) java(("`Java`")) -.-> java/ObjectOrientedandAdvancedConceptsGroup(["`Object-Oriented and Advanced Concepts`"]) java(("`Java`")) -.-> java/DataStructuresGroup(["`Data Structures`"]) java/FileandIOManagementGroup -.-> java/stream("`Stream`") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/arraylist("`ArrayList`") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/hashmap("`HashMap`") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/iterator("`Iterator`") java/FileandIOManagementGroup -.-> java/files("`Files`") java/FileandIOManagementGroup -.-> java/io("`IO`") java/FileandIOManagementGroup -.-> java/read_files("`Read Files`") java/DataStructuresGroup -.-> java/collections_methods("`Collections Methods`") subgraph Lab Skills java/stream -.-> lab-415586{{"`How to filter a collection using Stream API in Java`"}} java/arraylist -.-> lab-415586{{"`How to filter a collection using Stream API in Java`"}} java/hashmap -.-> lab-415586{{"`How to filter a collection using Stream API in Java`"}} java/iterator -.-> lab-415586{{"`How to filter a collection using Stream API in Java`"}} java/files -.-> lab-415586{{"`How to filter a collection using Stream API in Java`"}} java/io -.-> lab-415586{{"`How to filter a collection using Stream API in Java`"}} java/read_files -.-> lab-415586{{"`How to filter a collection using Stream API in Java`"}} java/collections_methods -.-> lab-415586{{"`How to filter a collection using Stream API in Java`"}} end

Introduction to Java Stream API

Java Stream API is a powerful feature introduced in Java 8 that allows you to process collections of data in a declarative and functional style. Streams provide a way to perform various operations on data, such as filtering, mapping, sorting, and reducing, without the need for explicit iteration or mutable state.

Understanding Streams

A stream is a sequence of elements that supports various operations to perform computations on those elements. Streams can be created from various data sources, such as collections, arrays, or even I/O resources. Streams provide a fluent API that allows you to chain multiple operations together, making your code more expressive and readable.

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> stream = numbers.stream();
stream.filter(n -> n % 2 == 0)
     .map(n -> n * 2)
     .forEach(System.out::println);

In the example above, we create a stream from a list of integers, filter the even numbers, map them to their doubled values, and then print the results.

Advantages of using Streams

  1. Declarative Programming: Streams allow you to express your intent in a more declarative way, focusing on what you want to achieve rather than how to achieve it.
  2. Parallelism: Streams can be easily parallelized, allowing you to take advantage of multi-core processors and improve performance.
  3. Laziness: Streams are lazy, meaning that operations are only performed when the final result is needed, which can improve efficiency.
  4. Fluent API: The stream API provides a fluent and expressive way to chain multiple operations together, making your code more readable and maintainable.

Exploring Stream Operations

Streams provide a wide range of operations that you can use to manipulate your data. Some of the most common operations include:

  • Filtering: Selecting elements based on a given predicate.
  • Mapping: Transforming elements using a function.
  • Sorting: Ordering elements based on a comparator.
  • Reducing: Combining elements into a single result.
  • Collecting: Gathering the results into a new data structure.

In the following sections, we'll dive deeper into the specific use of the Stream API for filtering collections.

Filtering Collections with Streams

Filtering is one of the most common operations performed on collections using the Java Stream API. Filtering allows you to select a subset of elements from a collection based on a given predicate.

Applying Filters

The filter() method is used to apply a filter to a stream. This method takes a lambda expression or a method reference as an argument, which represents the filtering condition.

List<String> names = Arrays.asList("John", "Jane", "Bob", "Alice");
Stream<String> filteredNames = names.stream()
                                   .filter(name -> name.startsWith("J"));
filteredNames.forEach(System.out::println);

In the example above, we create a stream from a list of names and then use the filter() method to select only the names that start with the letter "J".

Chaining Multiple Filters

You can chain multiple filter() calls to apply multiple filtering conditions to a stream.

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Stream<Integer> filteredNumbers = numbers.stream()
                                        .filter(n -> n % 2 == 0)
                                        .filter(n -> n > 5);
filteredNumbers.forEach(System.out::println);

In this example, we first filter the numbers to select only the even numbers, and then we apply a second filter to select only the even numbers greater than 5.

Combining Filters with Other Operations

Filtering can be combined with other stream operations, such as mapping, sorting, and reducing, to create more complex data transformations.

List<Person> persons = Arrays.asList(
    new Person("John", 30),
    new Person("Jane", 25),
    new Person("Bob", 35),
    new Person("Alice", 28)
);

List<String> youngAdultNames = persons.stream()
                                     .filter(p -> p.getAge() >= 18 && p.getAge() < 30)
                                     .map(Person::getName)
                                     .collect(Collectors.toList());

System.out.println(youngAdultNames);

In this example, we first filter the list of Person objects to select only the young adults (between 18 and 30 years old), then we map the Name property of each Person object, and finally we collect the results into a new list.

By understanding the power of filtering with the Java Stream API, you can effectively manipulate and process your collections of data. In the next section, we'll explore more practical examples of applying filters.

Applying Filters: Practical Examples

Now that you have a solid understanding of the basics of filtering with the Java Stream API, let's explore some practical examples to solidify your knowledge.

Filtering Strings

Suppose you have a list of strings and you want to select only the ones that have a specific length or start with a certain character.

List<String> words = Arrays.asList("apple", "banana", "cherry", "date", "elderberry");

// Filter words with length greater than 5 characters
List<String> longWords = words.stream()
                              .filter(word -> word.length() > 5)
                              .collect(Collectors.toList());
System.out.println(longWords); // [banana, cherry, elderberry]

// Filter words starting with 'a'
List<String> wordsStartingWithA = words.stream()
                                      .filter(word -> word.startsWith("a"))
                                      .collect(Collectors.toList());
System.out.println(wordsStartingWithA); // [apple, date]

Filtering Numbers

You can also use the Stream API to filter numerical data, such as integers or doubles.

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

// Filter even numbers
List<Integer> evenNumbers = numbers.stream()
                                  .filter(n -> n % 2 == 0)
                                  .collect(Collectors.toList());
System.out.println(evenNumbers); // [2, 4, 6, 8, 10]

// Filter numbers greater than 5
List<Integer> numbersGreaterThan5 = numbers.stream()
                                          .filter(n -> n > 5)
                                          .collect(Collectors.toList());
System.out.println(numbersGreaterThan5); // [6, 7, 8, 9, 10]

Filtering Custom Objects

You can also apply filters to collections of custom objects, such as Person objects.

class Person {
    private String name;
    private int age;

    // Getters, setters, and constructor
}

List<Person> persons = Arrays.asList(
    new Person("John", 30),
    new Person("Jane", 25),
    new Person("Bob", 35),
    new Person("Alice", 28)
);

// Filter persons older than 30
List<Person> personsOlderThan30 = persons.stream()
                                        .filter(p -> p.getAge() > 30)
                                        .collect(Collectors.toList());
System.out.println(personsOlderThan30); // [Person(name=Bob, age=35)]

// Filter persons with names starting with 'J'
List<Person> personsWithNameStartingWithJ = persons.stream()
                                                  .filter(p -> p.getName().startsWith("J"))
                                                  .collect(Collectors.toList());
System.out.println(personsWithNameStartingWithJ); // [Person(name=John, age=30), Person(name=Jane, age=25)]

By exploring these practical examples, you should now have a better understanding of how to effectively use the filter() method to manipulate your collections in Java.

Summary

By the end of this tutorial, you will have a solid understanding of how to use the Java Stream API to filter collections. You'll learn about the various filtering methods available, such as filter(), distinct(), and limit(), and how to apply them to your specific use cases. With the knowledge gained, you'll be able to write more efficient and maintainable Java code, optimizing your data processing workflows and unlocking the full potential of the Stream API.

Other Java Tutorials you may like