Java Supplier
最后修改时间:2024 年 3 月 5 日
在本文中,我们将展示如何在 Java 中使用 Supplier 函数式接口。
Supplier
Java Supplier 是一个函数式接口,表示返回结果的操作。Supplier 不接受任何参数。
一个 Supplier<T> 的设计目的是在不接受任何显式输入参数的情况下生成一个值。 它通过调用一个方法或在内部生成一个值来实现。
@FunctionalInterface
public interface Supplier<T> {
T get();
}
T 是 supplier 提供的结果的类型。
Supplier 提供了一种简洁方便的方式来表示提供值的函数,从而促进 Java 中惰性求值、代码清晰性和与函数式编程概念的兼容性。
简单的 Supplier 示例
以下示例创建了一个简单的 supplier。
void main() {
var words = List.of("falcon", "cup", "fun", "cloud");
var res = upperWords(words);
System.out.println(res);
}
List<String> upperWords(List<String> words) {
var uppered = new ArrayList<String>();
for (var word : words) {
Supplier<String> upperSupplier = word::toUpperCase;
uppered.add(upperSupplier.get());
}
return uppered;
}
该程序使用 upperSupplier 将单词转换为大写。
Supplier<String> upperSupplier = word::toUpperCase;
Supplier 返回一个字符串。 它引用 String 类型的 toUpperCase 方法。 它可能看起来像 supplier 接受一个参数,但它不是;它接受对一个方法(该方法本身接受参数)的引用。
表达式 word::toUpperCase 指的是特定 word 实例上 toUpperCase 方法的绑定方法引用。 由于 word 是循环中的一个变量,因此为每个单词单独创建一个新的 Supplier<String>。 Supplier 上的 Supplier<String> 方法只需调用该特定捕获实例上的 toUpperCase。
$ java Main.java [FALCON, CUP, FUN, CLOUD]
产品 Supplier
下一个示例创建了一个返回产品的函数。
Supplier<List<Product>> productSupplier = () -> {
return List.of(
new Product(1, "Product A"),
new Product(2, "Product B"),
new Product(3, "Product C"),
new Product(4, "Product D"),
new Product(5, "Product E"));
};
void main() {
productSupplier.get().stream().limit(3).forEach(System.out::println);
}
record Product(int id, String name) {
}
定义的 supplier 返回一个产品列表。
productSupplier.get().stream().limit(3).forEach(System.out::println);
我们使用 get 检索列表。 我们将其转换为流并从列表中获取前三个产品。
$ java Main.java Product[id=1, name=Product A] Product[id=2, name=Product B] Product[id=3, name=Product C]
IntSupplier
IntSupplier 表示 int 值结果的 supplier。 这是 Supplier 的 int 生成原始类型特化。
void main() {
IntSupplier randIntSupp = () -> new Random().nextInt(40);
System.out.println(randIntSupp.getAsInt());
System.out.println(randIntSupp.getAsInt());
System.out.println("--------------------");
IntStream.generate(randIntSupp).limit(6).forEach(System.out::println);
}
该程序创建了一个随机整数的 supplier。
IntSupplier randIntSupp = () -> new Random().nextInt(40);
IntSupplier 返回范围 [0,40) 内的随机整数。
System.out.println(randIntSupp.getAsInt());
我们使用 getAsInt 获取一个随机整数。
IntStream.generate(randIntSupp).limit(6).forEach(System.out::println);
生成了六个随机整数的流。
$ java Main.java 4 35 -------------------- 31 4 10 30 15 8
斐波那契值 Supplier
下一个示例创建了一个生成斐波那契数列的 supplier。
Supplier<Long> fibonacciSupplier = new Supplier<Long>() {
long a = 0, b = 1;
public Long get() {
long nextValue = a + b;
a = b;
b = nextValue;
return a;
}
};
void main() {
Stream<Long> fibs = Stream.generate(fibonacciSupplier);
fibs.limit(20).forEach(e -> System.out.print(STR."\{e} "));
}
我们从斐波那契 supplier 创建一个流并获取前二十个值。
$ java Main.java 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
CompletableFuture.supplyAsync
Supplier 接口用于各种 Java API 中。 例如,CompletableFuture.supplyAsync 返回一个异步完成的 CompletableFuture。
void main() throws ExecutionException, InterruptedException {
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
return new Random().nextInt(40);
});
System.out.println(future.get());
}
该程序在一个异步操作中返回范围 [0,40) 内的随机整数。
在本文中,我们使用了 Java Supplier 接口。
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
return new Random().nextInt(40);
});
CompletableFuture 将 Supplier 作为参数。
来源
在本文中,我们使用了 Supplier Java 接口。
作者
列出所有Java教程。