Статьи
YouTube-канал

Stream API

27 апреля 2018

Тэги: Collections Java 8 Stream API

Содержание

  1. Объединение нескольких строк в одну
  2. Сгенерить N одинаковых элементов
  3. Работа с произвольными типами
  4. Фильтрация элементов
  5. Среднее значение
  6. Преобразование элементов
  7. Чтение файла в строку
  8. Запись коллекции строк в файл

В Java 8 появилось довольно важное нововведение под названием Stream. И здесь имеются в виду не потоки ввода/вывода. Stream - это абстракция, позволяющая с любыми объектами работать как с потоками данных. Порой это чем-то похоже на выполнение запросов к БД. Рассмотрим несколько типовых задач, с которыми часто сталкивается каждый разработчик.

Объединение нескольких строк в одну

Наверняка вам приходилось генерить одну строку из нескольких других, разделённых запятыми. При этом после последнего элемента запятой быть не должно. Знакомо? В java 8 это делается так:

Stream.of("Linux", "Windows", "Mac")
    .collect(Collectors.joining(", ")));

Мы создаём новый поток из простых строк, а затем собираем их в одну при помощи метода collect(). В результате получим следующую строку:

Linux, Windows, Mac

Сгенерить N одинаковых элементов

Сгенерим три знака вопроса и вставим между ними запятые, аналогично предыдущей задаче:

Stream.generate(() -> "?")                
        .limit(3)                         
        .collect(Collectors.joining(", "))

Получим:

?, ?, ?

Работа с произвольными типами

Потоки могут работать с любыми типами объектов. Давайте создадим простой класс (модель данных), представляющий имя и возраст человека. Для наглядности также переопределим метод toString():

public class Person {

    private final String name;
    private final int age;
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return String.format("%s (%s)", name, age);
    }
}

Теперь инициализируем коллекцию, которую потом будем преобразовывать.

List<Person> persons = new ArrayList<>();
persons.add(new Person("Боб", 25));
persons.add(new Person("Алиса", 20));
persons.add(new Person("Николай Петрович", 60));

Фильтрация элементов

Выберем всех пользователей не старше 30 лет и выведем каждого из них на экран:

persons.stream()                       
        .filter(p -> p.getAge() <= 30)
        .forEach(System.out::println);

Обратите внимание, что Stream можно получить из любой коллекции при помощи метода stream(). Затем в методе filter() используем лямбда-выражение (вместо p можно использовать любое другое имя). В качестве выражения фильтрации можно использовать абсолютно любое выражение, возвращающее тип boolean. И наконец, для каждого из оставшихся элементов мы вызываем статическую функцию println(). Обратите внимание на её особую запись. Эту запись можно использовать в стримах для любого метода, принимающего один параметр.

В результате на экране увидим Боба и Алису, а вот Николаю Петровичу не повезло:

Боб (25)
Алиса (20)

Среднее значение

Подсчитаем средний возраст наших персон, используя другой коллектор:

persons.stream()                                          
        .collect(Collectors.averagingInt(Person::getAge))

Для метода Person.getAge() опять используем сокращённую запись. В результате получим, что средний возраст составляет 35,0 лет.

Преобразование элементов

Создадим новый стрим из строк, каждая из которых будет представлять имя персоны в верхнем регистре:

persons.stream()                            
        .map(p -> p.getName().toUpperCase())
        .collect(Collectors.joining(", "))

Результат:

БОБ, АЛИСА, НИКОЛАЙ ПЕТРОВИЧ

Чтение файла в строку

Прочитать все строки текстового файла и объединить их в одну строку можно так:

Path path = Paths.get(путь_до_файла);                        
Files.lines(path, StandardCharsets.UTF_8)                    
        .collect(Collectors.joining(System.lineSeparator()));

Обратите внимание, что для объединения строк здесь используется специальный метод System.lineSeparator(), возвращающий один или два символа перевода строки в зависимости от вашей ОС.

Запись коллекции строк в файл

Похожим образом производится и запись строк в файл:

Path path = Paths.get("путь_до_файла");
Files.write(path, Arrays.asList("first line", "second line"), StandardCharsets.UTF_8);

На выходе получим файл, состоящий из двух строк.


Облако тэгов

Kotlin, Java, Java 16, Java 11, Java 10, Java 9, Java 8, Spring, Spring Boot, Spring Data, SQL, PostgreSQL, Oracle, Hibernate, Collections, Stream API, многопоточность, ввод-вывод, Apache, maven, gradle, JUnit, YouTube, новости, ООП, алгоритмы, головоломки, rest, GraphQL, Excel, XML, json, yaml

Последние статьи


Комментарии

Добавить комментарий

×

devmark.ru