Какие встроенные функциональные интерфейсы в Java ты знаешь?

Ответ

Основные функциональные интерфейсы находятся в пакете java.util.function. Они являются целевыми типами для лямбда-выражений и ссылок на методы.

Интерфейс Сигнатура метода Назначение Пример использования
Predicate<T> boolean test(T t) Проверка условия (фильтрация). .filter(s -> s.isEmpty())
Function<T, R> R apply(T t) Преобразование объекта из типа T в тип R. .map(s -> s.length())
Consumer<T> void accept(T t) Выполнение действия над объектом (побочный эффект). .forEach(System.out::println)
Supplier<T> T get() Поставка (генерация) значения. () -> new ArrayList<>()
UnaryOperator<T> T apply(T t) Частный случай Function<T, T> для операций над одним типом. .replaceAll(s -> s.toUpperCase())
BiFunction<T, U, R> R apply(T t, U u) Функция, принимающая два аргумента. (a, b) -> a + b
BinaryOperator<T> T apply(T t1, T t2) Частный случай BiFunction<T,T,T>. .reduce((a, b) -> a + b)

Почему это важно: Эти интерфейсы стандартизируют передачу поведения, что является основой функционального программирования в Java и активно используется в Stream API и многопоточности (CompletableFuture).

Ответ 18+ 🔞

Слушай, а вот есть в джаве такая папка java.util.function. Это типа как набор стандартных заглушек, куда ты можешь воткнуть свою лямбду или ссылку на метод, чтобы не писать свои интерфейсы на каждый чих. Без них сейчас нихуя не работает — ни стримы, ни асинхронщина какая.

Смотри, табличка, чтобы не ебать мозг:

Как называется эта штука Что в ней за метод Зачем она нужна Где ты её, блядь, видел
Predicate<T> boolean test(T t) Это чтобы проверять что-то, типа фильтра. В стримах: .filter(s -> s.isEmpty()) — тут как раз предикат.
Function<T, R> R apply(T t) Берёт один тип, выплевывает другой. Преобразование, короче. .map(s -> s.length()) — строку в число превращает.
Consumer<T> void accept(T t) Сделать что-то с объектом, но ничего не вернуть. Побочный эффект, ёпта. .forEach(System.out::println) — просто жрёт и печатает.
Supplier<T> T get() Ничего не принимает, но что-то поставляет. Как фабрика или генератор. () -> new ArrayList<>() — создаёт новую пустую коллекцию.
UnaryOperator<T> T apply(T t) Частный случай функции, когда и вход, и выход — один тип. Унарная операция. .replaceAll(s -> s.toUpperCase()) — строку в верхний регистр.
BiFunction<T, U, R> R apply(T t, U u) Функция, но уже от двух аргументов. Берёт T и U, выдает R. (a, b) -> a + b — складывает два числа.
BinaryOperator<T> T apply(T t1, T t2) Частный случай предыдущего, когда все три типа одинаковые. Бинарная операция. .reduce((a, b) -> a + b) — сворачивает стрим.

А важно это всё, блядь, потому что это основа. Вся эта ваша функциональщина в Java на этом стоит. Хочешь в стримах что-то делать — ты жмёшь на эти интерфейсы. Хочешь в CompletableFuture колбэки цеплять — опять они. Стандартизация, ёбушки-воробушки, чтобы не изобретать велосипед каждый раз. Выучил раз — и похуй, везде одно и то же.