1.4. FP, Lambda, Stream API Flashcards

1
Q

Что такое lambda-выражение?

A

Лямбда-выражение - это краткая форма записи реализации абстрактного метода функционального интерфейса, которая может быть передана в качестве параметра.

  • Синтаксис: (параметры) -> { тело }.
  • В Java лямбда-выражение выполняет роль анонимной функции.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Что такое функциональные интерфейсы?

A

Функциональный интерфейс - это интерфейс, который содержат только один абстрактный метод, не считая методы класса Object.

  • Обозначается аннотацией @FunctionalInterface.
  • Примеры: Runnable, Comparator, Function, Supplier, Operator.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Перечислите функциональные интерфейсы из пакета java.util.function.

A
  • Supplier - ничего не принимает, возвращает объект.
  • Consumer (BiConsumer) - принимает объект и выполняет действие с ним, ничего не возвращает.
  • Predicate (BiPredicate) - проверяет условие, возвращает boolean.
  • Function (BiFunction) - преобразует входной параметр в значение другого типа.
  • UnaryOperator (BinaryOperator) - разновидность Function, где входной и выходной типы совпадают.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Что такое функции высшего порядка?

A

Функции высшего порядка — это функции, которые принимают или возвращают другие функции.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Какие функциональные интерфейсы из пакета java.util.function поддерживают функции высшего порядка?

A
  • Function, BiFunction: методы andThen(), compose().
  • Predicate, BiPredicate: методы and(), or(), negate().
  • Consumer, BiConsumer: метод andThen().

compose() - сначала выполнить указанную функцию, а затем применить текущую. Последовательность происходит в обратном порядке, чем при использовании andThen.

negate() - меняет результат текущего предиката на противоположный (true → false, false → true).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Что такое ссылки на методы?

A

Ссылки на методы (method references) — это сокращенный способ записи существующих методов в лямбда-выражении.

Типы ссылок:

  • Статический метод: СlassName::method
  • Метод объекта: instance::method
  • Конструктор: ClassName::new

Сигнатура ссылки на метод/конструктор должна совпадать с сигнатурой абстрактного метода функционального интерфейса.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Что такое ссылки на конструкторы?

A

Ссылки на конструкторы (ClassName::new) используются для создания объектов.

  • Без параметров: реализует Supplier<T>.</T>
  • С параметрами: реализует Function<T, R> или BiFunction<T, U, R>.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Расскажите о зоне видимости переменных в lambda – выражениях?

A
  • Поля класса и статические переменные: доступны для чтения и изменения.
  • Локальные переменные: доступны только для чтения, должны быть final или effectively final.
  • Переменные внутри лямбда-выражения: доступны только внутри.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Как быть в ситуации, если внутри lambda - выражения операторы могут выкинуть исключение?

A
  • Преобразовать исключение в RuntimeException в try-catch.
  • Использовать функциональный интерфейс, который декларирует checked exceptions в throws
    т.к. в Java нельзя выбросить checked исключение из метода, если оно не указано в throws.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Что такое Stream API?

A

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

Особенности: потоки не изменяют исходные данные.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Расскажите, какие шаблоны проектирования используются внутри Stream API? (Builder, Strategy, Decorator, Factory Method, Pipeline).

A
  • Builder - позволяет пошагово создавать сложные объекты, давая пользователю возможность комбинировать компоненты.
  • Strategy - обеспечивает выбор алгоритма выполнения во время работы программы.
  • Decorator - добавляет новую функциональность объекту, не изменяя его структуру.
  • Factory Method - создание потоков (Stream.of()) с использованием подклассов вместо прямого создания экземпляров.
  • Pipeline - конвейерная обработка данных через комбинацию промежуточных и терминальных операций.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Объясните, где они используются в Stream API.

A
  • Builder - создает цепочки операций (map(), filter(), sorted()) для обработки данных поэтапно.
  • Strategy - позволяет выбирать алгоритм выполнения (stream() или parallelStream()).
  • Decorator - методы filter(), map(), flatMap() и другие конвейерные операции действуют как декораторы, добавляя функциональность к потоку данных без изменения исходного источника данных.
  • Factory Method - создает потоки через методы Stream.of() и Arrays.stream().
  • Pipeline - представляет собой последовательность конвейерных операций, где каждая операция обрабатывает поток данных и передает результат следующей операции в цепочке.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Что такое конвейерные и терминальные операции?

A
  • Конвейерные операции - это промежуточные операции, которые выполняют преобразование данных и возвращают новый поток. Эти операции выполняются только после вызова терминальной операции.
  • Терминальные операции - инициируют выполнение всех промежуточных операций, возвращают результат и закрывают поток.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Перечислите конвейерные (промежуточные) методы Stream API.

A
  • filter() - фильтрует элементы потока по предикату.
  • map() - преобразует каждый элемент потока, применяя функцию.
  • flatMap() - объединяет вложенные потоки в один.
  • distinct() - удаляет дубликаты из потока.
  • sorted() - сортирует элементы потока по компаратору, по умолчанию (natural order).
  • peek() - выполняет действие для каждого элемента потока без изменения самого потока. Используется для отладки.
  • limit() - ограничивает количество элементов в потоке до заданного количества.
  • skip() - пропускает первые n элементов потока.

Дополнительные конвейерные методы для примитивных потоков:

  • mapToInt(), mapToLong(), mapToDouble() - преобразуют элементы потока в поток примитивов int, long, double.
  • flatMapToInt(), flatMapToLong(), flatMapToDouble() - преобразует элементы в поток примитивов int, long, double, затем объединяет все потоки в один.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Перечислите терминальные методы Stream API.

A
  • forEach() - выполняет действие для каждого элемента потока.
  • collect() - собирает элементы потока в коллекцию, строку или другой контейнер.
  • reduce() - выполняет агрегацию элементов, сводя их к одному результату.
  • count() - возвращает количество элементов в потоке.
  • toArray() - преобразует поток в массив.
  • min/max() - возвращает минимальный/максимальный элемент потока согласно компаратору.
  • findFirst() - возвращает первый элемент потока или Optional.empty.
  • findAny() - возвращает любой элемент потока.
  • allMatch() - проверяет, что все элементы соответствуют предикату.
  • noneMatch() - проверяет, что ни один элемент не соответствует предикату.
  • anyMatch() - проверяет, что хотя бы один элемент соответствует предикату.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Что такое отложенный выполнение lamdba?

A

Промежуточные операции потока выполняются только при вызове терминальной операции.

17
Q

Что делает метод filter()?

A

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

18
Q

Что делает метод map()?

A

map() - преобразует каждый элемент потока, применяя функцию и возвращает новый поток с результатами преобразования.

19
Q

Что делает метод flatMap()?

A

flatMap() - объединяет вложенные потоки в один.

20
Q

Что делает метод collect?

A

collect() - собирает элементы в коллекцию, массив и другую структуру данных.

21
Q

Что делает метод findFirst?

A

findFirst() - возвращает первый элемент потока в виде Optional.

22
Q

Что делает метод reduce?

A

reduce() - агрегирует элементы потока в одно значение. Ассоциативную бинарную операцию.

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

23
Q

Что делают методы min и max?

A

min()/max() - возвращают минимальный/максимальный элемент потока по компаратору. Терминальная операция, возвращает Optional<T>.

24
Q

Что делают методы count, sum, average?

A
  • count() - возвращает количество элементов потока.
  • sum() - возвращает сумму всех элементов потока примитивных типов IntStream, LongStream или DoubleStream. Для потоков объектов, таких как Stream<Integer>, необходимо использовать mapToInt() и затем применить sum().
  • average() - вычисляет среднее значение элементов в потоке примитивных типов IntStream, LongStream или DoubleStream. Возвращает OptionalDouble.
25
Q

Что делают методы forEach и peek?

A
  • forEach() - выполняет действие для каждого элемента потока. Терминальная операция.
  • peek() - выполняет промежуточное действие, не изменяя поток. Используется для отладки, логирования.
26
Q

Что делают методы skip и limit?

A
  • skip() - пропускает первые n элементов в начале потока.
  • limit() - оставляет первые n элементов. Возвращает новый поток, содержащий только первые n элементов исходного потока.
27
Q

Что делают методы allMatch(), noneMatch() и anyMatch()?

A
  • allMatch() - проверяет, что все элементы соответствуют предикату.
  • noneMatch() - проверяет, что ни один элемент не соответствует предикату.
  • anyMatch() - проверяет, что хотя бы один элемент предикату.

Все три метода терминальные, возвращающие boolean.

28
Q

Что делают методы mapToInt(), flatMapToInt(), mapToObj()?

A
  • mapToInt() - преобразует элементы в int и возвращает IntStream.
  • flatMapToInt() - преобразует каждый элемент потока в IntStream и объединяет все результирующие потоки в один IntStream.
  • mapToObj() - преобразует примитивный поток IntStream, LongStream, DoubleStream в любой объектный Stream<U>, используя функцию преобразования.
29
Q

Что такое числовой поток?

A

Числовой поток IntStream, LongStream, DoubleStream - это поток для работы с примитивными типами данных int, long и double.

Преимущества:

  • Не нужен autoboxing/unboxing примитивных типов.
  • Предоставляют методы sum(), average(), min(), max() и другие.
  • Меньше расход памяти.
30
Q

Чем отличается Stream<Integer> от IntStream<int>?

A
  • Stream<Integer> - поток объектов типа Integer, требуется autoboxing/unboxing, менее эффективен для чисел.
  • IntStream - поток примитивов типа int, не нужен autoboxing/unboxing, более производителен для числовых операций.
31
Q

Что делает метод boxed?

A

boxed() - преобразует примитивный поток в соответствующий ему объектный.

  • IntStreamStream<Integer>
  • LongStreamStream<Long>
  • DoubleStreamStream<Double>
32
Q

Возможно ли прервать выполнение потока по аналогии с break?

A

Да, в следующих случаях:
1. Раннее завершение:

  • anyMatch(), allMatch(), noneMatch() - останавливают поток при достижении результата.
  • findFirst(), findAny() - завершают поток после нахождения элемента.

2. Ограничение:

  • limit() - ограничивает число обрабатываемых элементов.
  • takeWhile() - завершает поток при первом несоответствии предикату.

3. Исключение: поток
прерывается вручную через выброс исключения.

33
Q

Возможно ли пропустить элемент потока по аналогии с continue?

A

В Stream API нет прямого аналога continue, но пропуск элементов возможен:

  • filter() - фильтрует элементы по предикату.
  • skip() - пропускает первые n элементов.
  • takeWhile() - завершает поток при первом несоответствии предикату.
34
Q

Что такое Optional?

A
  • Optional - это класс-обёртка для объекта, который может содержать значение или быть пустым.
  • Помогает избежать NullPointerException и предоставляет методы для обработки значений, которые могут быть пустыми.
35
Q

Перечислите методы Optional.

A
  • of() - создаёт Optional с непустым значением.
  • ofNullable() - создаёт Optional, допускающий null.
  • empty() - создаёт пустой Optional.
  • isPresent() - проверяет наличие значения.
  • isEmpty() - проверяет отсутствие значения.
  • get() - возвращает значение, если оно есть.
  • orElse() - возвращает значение или дефолтное.
  • orElseGet() - возвращает значение или результат Supplier.
  • orElseThrow() - выбрасывает исключение, если значения нет.
  • ifPresent() - выполняет действие, если значение есть.
  • ifPresentOrElse() - выполняет действие или альтернативно.
  • map() - преобразует значение применяя функцию.
  • flatMap() - преобразует значение в другой Optional, убирая вложенность Optional<Optional<T>>.
  • filter() - фильтрует элементы по предикату.
36
Q

В чем разница между методами orElse() и orElseGet()?

A
  • orElse() - всегда вычисляет и возвращает заданное значение, даже если оно не понадобится.
  • orElse() - вычисляет значение только при его необходимости, используя Supplier.
37
Q

Расскажите про фабричные методы List.of, Set.of, Map.of?

A

Эти методы создают неизменяемые коллекции и не поддерживают null:

  • List.of() - создаёт неизменяемый список.
  • Set.of() - создаёт неизменяемое множество.
  • Map.of() - создаёт неизменяемую карту (до 10 пар ключ-значение). Для карт с более чем 10 парами существует перегрузка Map.ofEntries().

Если неизменяемая коллекция содержит null, выбрасывается NullPointerException. Попытка изменения неизменяемую коллекцию выбросит UnsupportedOperationException.

38
Q

Для чего используется var?

A
  • var используется для упрощения кода, позволяя компилятору определять тип переменной по типу её значения.
  • var не является ключевым словом и зарезервировано как идентификатор, поэтому нельзя использовать как название переменной, метода итд.
39
Q

В каких случаях можно использовать var?

A

var можно использовать:

  • для локальных переменных.
  • в циклах for.
  • с лямбда-выражениями.

Нельзя использовать для полей класса, параметров метода и возвращаемых значений или если тип не может быть выведен однозначно.