Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
# Где применяется Supplier в Java?
Определение Supplier
Supplier<T> — это функциональный интерфейс, который не принимает аргументов и возвращает значение типа T.
@FunctionalInterface
public interface Supplier<T> {
T get();
}
Supplier — это поставщик/производитель значений.
1. Ленивая инициализация (Lazy Initialization)
public class DatabaseService {
public void executeQuery(Supplier<PreparedStatement> stmtSupplier) {
PreparedStatement stmt = stmtSupplier.get(); // Создаётся только здесь
stmt.executeQuery();
}
}
DatabaseService service = new DatabaseService();
service.executeQuery(() -> connection.prepareStatement("SELECT * FROM users"));
2. Default Values в Optional
public Optional<User> findById(Long id) {
return Optional.empty();
}
// Supplier для значения по умолчанию
public User getUserWithFallback(Long id) {
return findById(id).orElseGet(() -> new User("Guest", "guest@example.com"));
}
// Функция вызовется ТОЛЬКО если пользователя нет
public User getUserOrDefault(Long id) {
return findById(id).orElseGet(this::getDefaultUser);
}
3. Factory Pattern
public class ConnectionFactory {
public Supplier<Connection> createConnectionSupplier() {
return () -> {
System.out.println("Создаём новое подключение...");
return DriverManager.getConnection(url, username, password);
};
}
}
Supplier<Connection> connSupplier = factory.createConnectionSupplier();
Connection conn1 = connSupplier.get(); // Creates new connection
Connection conn2 = connSupplier.get(); // Creates another
4. Dependency Injection в Spring
@Component
public class UserService {
private final Supplier<UserRepository> repoSupplier;
@Autowired
public UserService(Supplier<UserRepository> repoSupplier) {
this.repoSupplier = repoSupplier;
}
public void processUsers() {
UserRepository repo = repoSupplier.get();
List<User> users = repo.findAll();
}
}
Spring автоматически внедрит Supplier<UserRepository>. Это избегает circular dependencies.
5. Функциональное программирование (Streams)
// Генерируем 10 случайных чисел
Supplier<Integer> randomSupplier = () -> (int) (Math.random() * 100);
Stream<Integer> randomNumbers = Stream.generate(randomSupplier).limit(10);
// Генерируем UUID
Supplier<String> uuidSupplier = () -> UUID.randomUUID().toString();
List<String> ids = Stream.generate(uuidSupplier).limit(5).collect(Collectors.toList());
// Генерируем объекты
Supplier<User> userSupplier = () -> new User("User" + System.nanoTime(), "user@example.com");
List<User> users = Stream.generate(userSupplier).limit(3).collect(Collectors.toList());
6. Кэширование и Memoization
public class CachedSupplier<T> implements Supplier<T> {
private final Supplier<T> supplier;
private T cachedValue;
private boolean initialized = false;
@Override
public synchronized T get() {
if (!initialized) {
cachedValue = supplier.get();
initialized = true;
}
return cachedValue;
}
}
Supplier<ExpensiveObject> supplier = new CachedSupplier<>(() -> new ExpensiveObject());
ExpensiveObject obj1 = supplier.get(); // создаёт
ExpensiveObject obj2 = supplier.get(); // из кэша
7. Логирование дорогостоящих операций
public void log(Supplier<String> messageSupplier) {
if (isDebugEnabled()) {
System.out.println(messageSupplier.get());
}
}
// Вычисление выполнится только если debug enabled
logger.log(() -> {
List<String> items = expensiveOperation();
return "Результат: " + items.size();
});
8. Обработка исключений
public static <T> T getOrNull(Supplier<T> supplier) {
try {
return supplier.get();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
String value = getOrNull(() -> riskyOperation());
Сравнение функциональных интерфейсов
| Интерфейс | Аргументы | Возврат | Пример |
|---|---|---|---|
Supplier<T> | НЕТ | T | поставщик |
Consumer<T> | T | void | печать |
Function<T,R> | T | R | преобразование |
Predicate<T> | T | boolean | проверка |
Главные применения
- Ленивая инициализация - дорогостоящие объекты создаются только когда нужны
- Factory pattern - создание объектов по требованию
- Значения по умолчанию в Optional.orElseGet()
- Dependency Injection - внедрение зависимостей в Spring
- Stream.generate() - генерация потоков
- Кэширование - ленивое кэширование значений
- Логирование - вычисление только при необходимости
Главное преимущество: Вычисление откладывается до момента, когда значение действительно нужно.