Актуальная версия статьи доступна на моём сайте devmark.ru
В Java 8 появилось довольно важное нововведение под названием Stream. И здесь имеются в виду не потоки ввода/вывода. Stream - это абстракция, позволяющая с любыми объектами работать как с потоками. Порой это чем-то похоже на выполнение запросов к БД. Рассмотрим несколько типовых задач, с которыми часто сталкивается каждый разработчик.
Мы создаём новый поток из простых строк, а затем собираем их в одну при помощи метода collect. В результате получим следующую строку:
Linux, Windows, Mac
Получим:
?, ?, ?
Теперь инициализируем коллекцию, которую потом будем преобразовывать.
Обратите внимание, что Stream можно получить из любой коллекции при помощи метода stream(). Затем в методе filter используем лямбда-выражение (вместо p можно использовать любое другое имя). В качестве выражения фильтрации можно использовать абсолютно любое выражение, возвращающее тип boolean. И наконец, для каждого из оставшихся элементов мы вызываем статическую функцию println. Обратите внимание на её особую запись. Эту запись можно использовать для любого метода, принимающего один параметр.
В результате на экране увидим Боба и Алису, а вот Николаю Петровичу не повезло:
Боб (25)
Алиса (20)
Для метода Person.getAge опять используем сокращённую запись. В результате получим, что средний возраст составляет 35,0 лет.
Создадим новый стрим из строк, каждая из которых будет представлять имя персоны в верхнем регистре:
Результат:
БОБ, АЛИСА, НИКОЛАЙ ПЕТРОВИЧ
Обратите внимание, что для объединения строк здесь используется платформенно-независимый метод System.lineSeparator(), возращающий один или два символа перевода строки в зависимости от вашей ОС.
На выходе получим файл, состоящий из двух строк.
В 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);
На выходе получим файл, состоящий из двух строк.
Комментариев нет:
Отправить комментарий