Как фильтровать коллекцию с использованием Stream API в Java

JavaJavaBeginner
Практиковаться сейчас

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

Java Stream API предоставляет мощный и гибкий способ работы с коллекциями данных. В этом руководстве мы рассмотрим, как использовать Stream API для фильтрации коллекций, что позволит вам эффективно извлекать нужные данные. Независимо от того, являетесь ли вы начинающим Java-разработчиком или опытным программистом, в этом руководстве вы найдете знания и навыки, которые помогут вам упростить задачи обработки данных.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL java(("Java")) -.-> java/ObjectOrientedandAdvancedConceptsGroup(["Object-Oriented and Advanced Concepts"]) java(("Java")) -.-> java/FileandIOManagementGroup(["File and I/O Management"]) java(("Java")) -.-> java/DataStructuresGroup(["Data Structures"]) java/DataStructuresGroup -.-> java/collections_methods("Collections Methods") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/arraylist("ArrayList") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/hashmap("HashMap") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/iterator("Iterator") java/FileandIOManagementGroup -.-> java/files("Files") java/FileandIOManagementGroup -.-> java/read_files("Read Files") java/FileandIOManagementGroup -.-> java/io("IO") java/FileandIOManagementGroup -.-> java/stream("Stream") subgraph Lab Skills java/collections_methods -.-> lab-415586{{"Как фильтровать коллекцию с использованием Stream API в Java"}} java/arraylist -.-> lab-415586{{"Как фильтровать коллекцию с использованием Stream API в Java"}} java/hashmap -.-> lab-415586{{"Как фильтровать коллекцию с использованием Stream API в Java"}} java/iterator -.-> lab-415586{{"Как фильтровать коллекцию с использованием Stream API в Java"}} java/files -.-> lab-415586{{"Как фильтровать коллекцию с использованием Stream API в Java"}} java/read_files -.-> lab-415586{{"Как фильтровать коллекцию с использованием Stream API в Java"}} java/io -.-> lab-415586{{"Как фильтровать коллекцию с использованием Stream API в Java"}} java/stream -.-> lab-415586{{"Как фильтровать коллекцию с использованием Stream API в Java"}} end

Введение в Java Stream API

Java Stream API - это мощная функция, введенная в Java 8, которая позволяет обрабатывать коллекции данных в декларативном и функциональном стиле. Потоки (streams) предоставляют способ выполнения различных операций над данными, таких как фильтрация, преобразование, сортировка и агрегация, без необходимости явной итерации или изменения состояния.

Понимание потоков (streams)

Поток (stream) - это последовательность элементов, которая поддерживает различные операции для выполнения вычислений над этими элементами. Потоки могут быть созданы из различных источников данных, таких как коллекции, массивы или даже ресурсы ввода-вывода. Потоки предоставляют удобный API, который позволяет объединять несколько операций, делая ваш код более выразительным и читаемым.

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);

В приведенном выше примере мы создаем поток из списка целых чисел, фильтруем четные числа, преобразуем их в удвоенные значения, а затем выводим результаты.

Преимущества использования потоков (streams)

  1. Декларативное программирование: Потоки позволяют выражать свою цель более декларативно, сосредотачиваясь на том, что вы хотите достичь, а не на том, как это сделать.
  2. Параллелизм: Потоки могут быть легко параллелизированы, что позволяет использовать преимущества многоядерных процессоров и повысить производительность.
  3. Ленивость: Потоки ленивые, то есть операции выполняются только тогда, когда нужен конечный результат, что может повысить эффективность.
  4. Удобный API: Stream API предоставляет удобный и выразительный способ объединения нескольких операций, делая ваш код более читаемым и поддерживаемым.

Исследование операций потоков (streams)

Потоки предоставляют широкий спектр операций, которые можно использовать для манипуляции данными. Некоторые из наиболее распространенных операций включают:

  • Фильтрация: Выбор элементов на основе заданного предиката.
  • Преобразование: Преобразование элементов с использованием функции.
  • Сортировка: Упорядочивание элементов на основе компаратора.
  • Агрегация: Объединение элементов в один результат.
  • Сбор: Сбор результатов в новую структуру данных.

В следующих разделах мы более подробно рассмотрим конкретное использование Stream API для фильтрации коллекций.

Фильтрация коллекций с использованием потоков (streams)

Фильтрация является одной из наиболее распространенных операций, выполняемых над коллекциями с использованием Java Stream API. Фильтрация позволяет выбрать подмножество элементов из коллекции на основе заданного предиката.

Применение фильтров

Метод filter() используется для применения фильтра к потоку (stream). Этот метод принимает в качестве аргумента лямбда-выражение или ссылку на метод, которое представляет условие фильтрации.

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

В приведенном выше примере мы создаем поток из списка имен и затем используем метод filter() для выбора только тех имен, которые начинаются с буквы "J".

Цепочка нескольких фильтров

Вы можете объединять несколько вызовов метода filter() для применения нескольких условий фильтрации к потоку (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);

В этом примере мы сначала фильтруем числа, чтобы выбрать только четные, а затем применяем второй фильтр, чтобы выбрать только четные числа, большие 5.

Комбинирование фильтров с другими операциями

Фильтрацию можно комбинировать с другими операциями потоков (streams), такими как преобразование (mapping), сортировка (sorting) и агрегация (reducing), чтобы создать более сложные преобразования данных.

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);

В этом примере мы сначала фильтруем список объектов Person, чтобы выбрать только молодых взрослых (от 18 до 30 лет), затем преобразуем (map) свойство Name каждого объекта Person, и в конце собираем (collect) результаты в новый список.

Понимая мощь фильтрации с использованием Java Stream API, вы можете эффективно манипулировать и обрабатывать свои коллекции данных. В следующем разделе мы рассмотрим более практические примеры применения фильтров.

Применение фильтров: практические примеры

Теперь, когда вы хорошо понимаете основы фильтрации с использованием Java Stream API, давайте рассмотрим несколько практических примеров, чтобы закрепить свои знания.

Фильтрация строк

Предположим, у вас есть список строк, и вы хотите выбрать только те, которые имеют определенную длину или начинаются с определенного символа.

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

// Фильтрация слов с длиной более 5 символов
List<String> longWords = words.stream()
                              .filter(word -> word.length() > 5)
                              .collect(Collectors.toList());
System.out.println(longWords); // [banana, cherry, elderberry]

// Фильтрация слов, начинающихся с 'a'
List<String> wordsStartingWithA = words.stream()
                                      .filter(word -> word.startsWith("a"))
                                      .collect(Collectors.toList());
System.out.println(wordsStartingWithA); // [apple, date]

Фильтрация чисел

Вы также можете использовать Stream API для фильтрации числовых данных, таких как целые числа или числа с плавающей точкой.

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); // [2, 4, 6, 8, 10]

// Фильтрация чисел, больших 5
List<Integer> numbersGreaterThan5 = numbers.stream()
                                          .filter(n -> n > 5)
                                          .collect(Collectors.toList());
System.out.println(numbersGreaterThan5); // [6, 7, 8, 9, 10]

Фильтрация пользовательских объектов

Вы также можете применять фильтры к коллекциям пользовательских объектов, таких как объекты Person.

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)
);

// Фильтрация людей старше 30 лет
List<Person> personsOlderThan30 = persons.stream()
                                        .filter(p -> p.getAge() > 30)
                                        .collect(Collectors.toList());
System.out.println(personsOlderThan30); // [Person(name=Bob, age=35)]

// Фильтрация людей с именами, начинающимися с 'J'
List<Person> personsWithNameStartingWithJ = persons.stream()
                                                  .filter(p -> p.getName().startsWith("J"))
                                                  .collect(Collectors.toList());
System.out.println(personsWithNameStartingWithJ); // [Person(name=John, age=00), Person(name=Jane, age=25)]

Изучив эти практические примеры, вы должны теперь лучше понимать, как эффективно использовать метод filter() для манипуляции коллекциями в Java.

Резюме

По окончании этого руководства вы будете хорошо понимать, как использовать Java Stream API для фильтрации коллекций. Вы узнаете о различных методах фильтрации, таких как filter(), distinct() и limit(), и как применять их в своих конкретных сценариях использования. С полученными знаниями вы сможете писать более эффективный и поддерживаемый Java-код, оптимизировать свои рабочие процессы обработки данных и раскрыть всю мощь Stream API.