Java Supplier接口
什么是Supplier接口?
Supplier接口是Java 8引入的函数式接口之一,它位于java.util.function
包中。Supplier接口是一个不接受任何参数但返回一个结果的函数式接口。这个接口特别适合于延迟计算、懒加载等场景。
简单来说,Supplier就是一个"提供者",它不需要输入,只负责提供(返回)一个值。
Supplier接口的基本定义
Supplier接口只有一个抽象方法:get()
。它的定义如下:
@FunctionalInterface
public interface Supplier<T> {
T get();
}
这个接口是泛型的,类型参数T
表示返回值的类型。
如何使用Supplier接口
基本用法
使用Supplier接口的最简单方式是通过Lambda表达式:
import java.util.function.Supplier;
public class SupplierExample {
public static void main(String[] args) {
// 创建一个返回字符串的Supplier
Supplier<String> helloSupplier = () -> "Hello, World!";
// 调用get()方法获取结果
String result = helloSupplier.get();
System.out.println(result); // 输出: Hello, World!
}
}
输出:
Hello, World!
使用方法引用
除了Lambda表达式,我们也可以使用方法引用来创建Supplier实例:
import java.util.function.Supplier;
import java.time.LocalDateTime;
public class MethodReferenceExample {
public static void main(String[] args) {
// 使用方法引用,引用LocalDateTime::now静态方法
Supplier<LocalDateTime> dateTimeSupplier = LocalDateTime::now;
System.out.println("当前时间是:" + dateTimeSupplier.get());
// 短暂延迟后再次调用
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("1秒后的时间是:" + dateTimeSupplier.get());
}
}
输出(具体时间会有所不同):
当前时间是:2023-07-21T14:30:45.123
1秒后的时间是:2023-07-21T14:30:46.124
创建对象实例
Supplier接口常用于创建对象实例:
import java.util.function.Supplier;
import java.util.ArrayList;
import java.util.List;
public class ObjectCreationExample {
public static void main(String[] args) {
// 使用构造器引用创建ArrayList的Supplier
Supplier<List<String>> listSupplier = ArrayList::new;
// 获取新的ArrayList实例
List<String> list = listSupplier.get();
list.add("Java");
list.add("Python");
System.out.println("列表内容:" + list);
// 再次调用,获取另一个新的实例
List<String> anotherList = listSupplier.get();
System.out.println("新列表是空的吗?" + anotherList.isEmpty()); // 输出: true
}
}
输出:
列表内容:[Java, Python]
新列表是空的吗?true
Supplier的特殊应用
延迟计算(Lazy Evaluation)
Supplier的一个重要用途是支持延迟计算,只有在需要结果时才执行计算:
import java.util.function.Supplier;
public class LazyEvaluationExample {
public static void main(String[] args) {
// 创建一个代表复杂计算的Supplier
Supplier<Double> complexCalculation = () -> {
System.out.println("执行复杂计算...");
// 模拟一些计算密集型操作
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return Math.random() * 100;
};
System.out.println("准备开始...");
// 只有在我们调用get()时,计算才会执行
if (Math.random() > 0.5) {
System.out.println("需要计算结果:" + complexCalculation.get());
} else {
System.out.println("不需要计算,跳过");
}
System.out.println("程序结束");
}
}
这个例子中,复杂计算只会在随机条件满足时才执行,这是延迟计算的一个好处。
实现Factory模式
Supplier接口很适合用来实现简单的工厂模式:
import java.util.function.Supplier;
import java.util.HashMap;
import java.util.Map;
// 产品接口
interface Product {
String getName();
}
// 具体产品类
class ConcreteProductA implements Product {
@Override
public String getName() {
return "Product A";
}
}
class ConcreteProductB implements Product {
@Override
public String getName() {
return "Product B";
}
}
// 使用Supplier的工厂
public class FactoryExample {
// 产品注册表
private static final Map<String, Supplier<Product>> PRODUCT_REGISTRY = new HashMap<>();
static {
// 注册产品创建方式
PRODUCT_REGISTRY.put("A", ConcreteProductA::new);
PRODUCT_REGISTRY.put("B", ConcreteProductB::new);
}
// 工厂方法
public static Product createProduct(String productType) {
Supplier<Product> productSupplier = PRODUCT_REGISTRY.get(productType);
if (productSupplier == null) {
throw new IllegalArgumentException("未知产品类型: " + productType);
}
return productSupplier.get();
}
public static void main(String[] args) {
Product productA = createProduct("A");
Product productB = createProduct("B");
System.out.println(productA.getName()); // 输出: Product A
System.out.println(productB.getName()); // 输出: Product B
}
}
实现缓存和默认值
Supplier可以用于实现简单的缓存或提供默认值:
import java.util.function.Supplier;
public class CachingExample {
public static void main(String[] args) {
String value = null; // 可能是null的值
// 创建提供默认值的Supplier
Supplier<String> defaultValueSupplier = () -> {
System.out.println("生成默认值");
return "Default Value";
};
// 使用orElseGet获取值或默认值
String result = (value != null) ? value : defaultValueSupplier.get();
System.out.println("结果: " + result);
// 在Java 8+ 中,可以使用Optional
import java.util.Optional;
String optionalResult = Optional.ofNullable(value).orElseGet(defaultValueSupplier);
System.out.println("Optional结果: " + optionalResult);
}
}
提示
Java 的 Optional
类中的 orElseGet
方法就接受一个 Supplier 参数,用于在值不存在时提供默认值。这比直接使用 orElse
更高效,因为只有在需要时才会计算默认值。