Ответ
Supplier<T> — это функциональный интерфейс из пакета java.util.function, который не принимает аргументов, но возвращает результат типа T. Его единственный абстрактный метод — T get().
Основное назначение: отложенная (ленивая) генерация или поставка значений.
Примеры использования:
-
Ленивая инициализация или генерация данных:
Supplier<String> uniqueIdSupplier = () -> UUID.randomUUID().toString(); System.out.println(uniqueIdSupplier.get()); // Вызовет генерацию UUID -
Использование в Stream API и коллекторах:
// Поставщик новой коллекции для Collectors.toCollection Supplier<ArrayList<String>> listSupplier = ArrayList::new; List<String> filteredList = someStream.collect(Collectors.toCollection(listSupplier)); -
Реализация паттерна «Стратегия» или кэширования:
Map<String, Supplier<Object>> strategyMap = new HashMap<>(); strategyMap.put("A", () -> expensiveOperationA()); strategyMap.put("B", () -> expensiveOperationB()); // Операция выполнится только при вызове get() Object result = strategyMap.get(key).get();
Ключевые особенности:
- Не имеет входных параметров.
- Может выбрасывать проверяемые исключения (требует обработки внутри лямбды или обёртки).
- Часто используется вместе с
Optional.orElseGet(Supplier)для ленивого предоставления значения по умолчанию. - Является противоположностью
Consumer<T>, который принимает значение, но ничего не возвращает.
Ответ 18+ 🔞
Давай разжую про этого Supplier<T>, а то смотрю, у некоторых глаза уже стекленеют. Представь себе такую хуйню: это как волшебный мешок, из которого можно достать что угодно, но только когда сам засунешь туда руку и скажешь «дай!». Сам по себе мешок пустой, он просто обещает, что внутри что-то есть.
По-пацански: это интерфейс с одним-единственным методом — T get(). Ничего не принимает, просто возвращает тебе что-то типа T. Всё. Больше от него нихуя.
Зачем это, спрашиваешь? А вот представь: ты не хочешь что-то вычислять или создавать прямо сейчас, потому что это может быть долго, или дорого, или вообще не факт, что пригодится. Ты говоришь: «Вот тебе, программа, инструкция, как это сделать. А когда понадобится — сам сделаешь и принесешь». Это и есть ленивая, блядь, инициализация в чистом виде.
Примеры, чтобы не быть пустобрёхом:
-
Ленивая генерация, ёпта. Не хочешь создавать ID, пока не нужно? Вот тебе поставщик:
Supplier<String> idGenerator = () -> UUID.randomUUID().toString(); // Тишина. Ничего не происходит. // Пока не позовёшь: String id = idGenerator.get(); // Вот тут-то он и вспотеет, сука, и сгенерит. -
В Stream API — поставщик новых коллекций. Когда собираешь стрим в конкретную коллекцию, надо сказать, как именно её создавать:
Supplier<TreeSet<String>> treeSetMaker = TreeSet::new; List<String> sortedUnique = someList.stream() .collect(Collectors.toCollection(treeSetMaker)); // Коллектор будет тыкать в этого поставщика каждый раз, когда надо новый TreeSet. -
Паттерн «Стратегия» или ленивый кэш. Допустим, у тебя есть тяжёлые операции, и ты не хочешь их все запускать сразу, как дурак:
Map<String, Supplier<BigDecimal>> priceCalculators = new HashMap<>(); priceCalculators.put("VIP", () -> calculateVipPrice()); // calculateVipPrice() НЕ вызывается тут! priceCalculators.put("DISCOUNT", () -> calculateDiscountPrice()); // А вот тут, когда ключ найден, — вызывается get() и, соответственно, тяжёлый метод. BigDecimal myPrice = priceCalculators.get("VIP").get();
Важные фишки, чтобы не обосраться:
- Аргументы — ноль. Вообще. Ничего не передаёшь.
- Исключения. Если твоя лямбда внутри может выбросить проверяемое исключение (типа
IOException), тебе придётся либо завернуть его вtry-catchпрямо внутри, либо использовать хитрые обёртки — самSupplierна это не рассчитан. - Оппозит
Consumerу.Supplier— даёт,Consumer— принимает. Как я и мой холодильник. - Лучший друг
Optional. ВместоOptional.orElse(value), который вычисляет значение всегда, даже если оно не нужно, естьOptional.orElseGet(Supplier). Поставщик сработает только если опционал пустой. Экономия, блядь, ресурсов!
Короче, Supplier<T> — это такой заготовленный пинок под жопу для твоего кода, который говорит: «Не сейчас, позже, когда скажут». Используй, когда хочешь отложить создание объекта или выполнение операции до последнего, ебать, момента.