1.4. FP, Lambda, Stream API Flashcards
Что такое lambda-выражение?
Лямбда-выражение - это анонимный класс, реализующий метод функционального интерфейса, который записан с использованием особого синтаксиса (лямбда оператора) и может быть передан в качестве параметра.
Что такое функциональные интерфейсы?
Функциональный интерфейс - это интерфейс, который может содержать один и только один абстрактный метод, не считая методов класса Object. Например equals().
Перечислите функциональные интерфейсы из пакета java.util.function.
- Supplier;
- Consumer (BiConsumer);
- Predicate (BiPredicate);
- Function (BiFunction);
- UnaryOperator и BinaryOperator.
Что такое функции высшего порядка?
Функции высшего порядка - это функции, зависящие от других функций.
Какие функциональные интерфейсы из пакета java.util.function поддерживают функции высшего порядка?
- Function: принимает один аргумент и возвращает результат.
- UnaryOperator: является подтипом Function и представляет операцию над одним операндом, возвращающую результат того же типа.
- BinaryOperator: является подтипом BiFunction и представляет операцию над двумя операндами, возвращающую результат того же типа.
Что такое ссылки на методы?
Существуют методы, которые могут принимать в качестве параметра ссылку на функциональный интерфейс или его реализацию в виде лямбда-выражения. Вместо этого, в такой метод можно передать ссылку на метод, который совпадает по сигнатуре с ожидаемым функциональным интерфейсом. То есть, по сути, может его реализовать.
Ссылка на метод выглядит так: ИмяКласса::ИмяМетода
Что такое ссылки на конструкторы?
Ссылка на конструктор является тем же, что и ссылка на метод, выглядит она так: ИмяКласса::new
Расскажите о зоне видимости переменных в lambda – выражениях?
Лямбда-выражение имеет доступ:
1. К полям класса объемлющего метода и может их изменять.
2. К локальным переменным объемлющего метода, но не может их изменять и эти переменные должны быть либо final, либо effectively final. В противном случае, мы получим ошибку компиляции.
3. Переменные объявленные внутри лямбда-выражения, доступны только в лямбда-выражении.
Как быть в ситуации, если внутри lambda - выражения операторы могут выкинуть исключение?
Лямбда-выражение может генерировать исключения и, в случае, если исключение является проверяемым, то оно должно быть описано в реализуемом функциональном интерфейсе после оператора throws.
Что такое Stream API?
Stream API — это часть Java API, которая была введена в Java 8 для облегчения работы с коллекциями данных и выполнения операций на них в функциональном стиле. Stream API предоставляет возможность создавать и манипулировать потоками данных.
Существует 3 возможных этапа потока:
1. Фильтрация;
2. Преобразование;
3. Упрощение или аккумуляция.
Расскажите, какие шаблоны проектирования используются внутри Stream API? (Builder, Strategy, Decorator, Factory Method, Pipeline).
- Фабричный метод,
- Билдер,
- Декоратор,
- Стратегия,
- Пайплайн.
Объясните, где они используются в Stream API.
Декоратор используется для добавления новых функциональностей объекту, не изменяя его структуру.
Фабричный метод используется для создания объектов с использованием подклассов вместо создания экземпляров напрямую.
Стратегия позволяет выбирать алгоритм выполнения во время выполнения программы.
Шаблон Строитель используется для пошагового создания сложных объектов, позволяя пользователю выбирать и комбинировать компоненты.
Конвейер - это архитектурный шаблон, в котором данные обрабатываются последовательно несколькими компонентами, называемыми этапами конвейера.
В Stream API, конвейер представляет собой последовательность конвейерных операций, где каждая операция обрабатывает поток данных и передает результат следующей операции в цепочке.
Что такое конвейерные и терминальные операции?
Конвейерные операции промежуточные. Они применяются к потоку данных и возвращают новый поток, который можно использовать для последующих операций. Эти операции выполняются лениво, то есть не вызывают фактического вычисления до тех пор, пока не будет вызвана терминальная операция.
Терминальные операции завершают обработку потока данных и возвращают конечный результат (или нет, если операция возвращает void). После выполнения терминальной операции поток данных больше не может быть использован.
Перечислите конвейерные (промежуточные) методы Stream API.
- filter() - фильтрует элементы потока, возвращая только элементы, удовлетворяющие условию.
- map() - преобразует каждый элемент потока.
- mapToInt() - тот же map(), но возвращает поток примитивов int (также есть соответствующие mapToDouble() и mapToLong()).
- flatMap() - трансформирует каждый объект потока в поток других объектов, то есть все элементы коллекции коллекций или потока потоков трансформирует в единый поток. (также поддерживает возврат потоков примитивов с помощью методов flatMapToInt(), flatMapToDouble(), flatMapToLong()). Может преобразовывать элементы, применяя указанную функцию к каждому элементу.
- peek() - применяет функцию Consumer к каждому элементу потока.
- sorted() - сортирует элементы потока по возрастанию. Возможна сортировка по убыванию при передаче соответствующего компаратора.
- skip() - пропускает указанное число элементов с начала потока.
- limit() - делает выборку первых элементов из родного потока в указанном количестве (отбирает элементы из потока, пока не достигнет указанного количества).
- distinct() - убирает дубликаты из потока.
- mapToObj() - трансформирует числовой поток в объектный.
Перечислите терминальные методы Stream API.
- forEach() - применяет функцию к каждому элементу потока.
- collect() - собирает все элементы потока в структуру данных.
- toArray() - собирает элементы потока в массив.
- count() - возвращает количество элементов в потоке.
- min() - возвращает минимальный элемент (условие передается в компараторе).
- max() - возвращает максимальный элемент (условие передается в компараторе).
- sum() - возвращает сумму всех элементов потока (только для числовых потоков).
- average() - возвращает среднее арифметическое всех элементов потока (только для числовых потоков).
- allMatch() - возвращает true, если все элементы удовлетворяют условию.
- noneMatch() - возвращает true, если все элементы не удовлетворяют условию.
- findFirst() - возвращает Optional с первым элементом потока (если он есть), иначе возвращает пустой Optional.
- findAny() - возвращает Optional со случайным элементом потока.
- anyMatch() - возвращает true, если хотя бы один элемент удовлетворяет условию.