Java 中的方法引用
方法引用可以有不同的形式,取决于方法的来源和使用场景。主要有四种形式:
-
静态方法引用:
ClassName::staticMethod示例:
Math::max; // 等价于 (a, b) -> Math.max(a, b) -
实例方法引用(特定对象的方法):
instance::instanceMethod示例:
System.out::println; // 等价于 x -> System.out.println(x) -
实例方法引用(任意对象的方法):
ClassName::instanceMethod示例:
String::toLowerCase; // 等价于 x -> x.toLowerCase() -
构造方法引用:
ClassName::new示例:
ArrayList::new; // 等价于 () -> new ArrayList<>()
- 方法引用有四种主要形式:静态方法引用、实例方法引用(特定对象或任意对象)、以及构造方法引用。它们是简化 Lambda 表达式的方式。
import java.util.function.Supplier;
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public static void main(String[] args) {
// 构造函数引用
Supplier<Person> personSupplier = Person::new;
// 实例方法引用(任意对象)
Supplier<String> nameSupplier = personSupplier.get()::getName;
// 使用实例方法引用
System.out.println(nameSupplier.get()); // 打印 name
}
}
Supplier 是 Java 8 引入的一个函数式接口,位于 java.util.function 包中。它的主要作用是提供一个结果,不接收任何输入参数。Supplier 常用于需要延迟计算或惰性求值的场景,也就是在需要时提供一个值,而不立即计算或创建它。
Supplier 的定义
Supplier 是一个泛型接口,定义如下:
@FunctionalInterface
public interface Supplier<T> {
T get();
}
T:代表返回值的类型。get():是唯一需要实现的方法,调用它会返回类型T的值。
使用场景
Supplier 通常用于生成或提供一个值、对象,或者用于懒加载。当我们想要推迟某些计算直到调用方真正需要它时,Supplier 就非常有用。
示例 1:基本使用 Supplier
下面的例子展示了如何使用 Supplier 来提供一个字符串:
import java.util.function.Supplier;
public class SupplierExample {
public static void main(String[] args) {
// 使用 Supplier 提供一个字符串
Supplier<String> stringSupplier = () -> "Hello, World!";
// 调用 get() 获取结果
System.out.println(stringSupplier.get()); // 输出 "Hello, World!"
}
}
在这个例子中,Supplier<String> 是一个返回字符串的 Supplier,调用 get() 方法时返回 "Hello, World!"。
示例 2:使用 Supplier 延迟计算
Supplier 还可以用于延迟计算,例如只有在需要的时候才计算某个值:
import java.util.function.Supplier;
public class LazyEvaluationExample {
public static void main(String[] args) {
Supplier<Double> randomSupplier = () -> Math.random();
// 延迟生成随机数
System.out.println("First call: " + randomSupplier.get());
System.out.println("Second call: " + randomSupplier.get());
}
}
每次调用 randomSupplier.get() 都会生成一个新的随机数。这就是 Supplier 的延迟计算的优势,只有在真正需要时才会执行。
示例 3:使用 Supplier 创建对象
Supplier 还可以用于创建对象,尤其是在构造函数引用中非常常见。
import java.util.function.Supplier;
public class Person {
private String name;
public Person() {
this.name = "John Doe";
}
public String getName() {
return name;
}
public static void main(String[] args) {
// 使用 Supplier 提供一个 Person 实例
Supplier<Person> personSupplier = Person::new;
// 延迟创建 Person 对象
Person person = personSupplier.get();
System.out.println("Person's name: " + person.getName()); // 输出 "John Doe"
}
}
在这个例子中,Person::new 是构造方法引用,返回一个新的 Person 实例。Supplier 提供了一种惰性加载对象的方式,只有在 get() 被调用时才创建 Person 对象。
Supplier<T>是一个不接受任何参数,但会返回类型T的值的函数式接口。- 它用于延迟计算、惰性求值或者对象创建。
- 通过调用
get()方法,可以获取由Supplier提供的值或对象。
Supplier 常用于需要提供值的场景,特别是在不确定何时需要这个值时,它是延迟计算的有效工具。
如果你需要一个能够接受参数并返回结果的函数式接口,那么应该使用 Java 8 中的另一个函数式接口,而不是 Supplier。Supplier 只适用于不需要参数的场景。如果需要传递参数并返回结果,可以使用以下接口:
1. Function<T, R>:接收一个参数并返回一个结果
- 定义:
Function<T, R>接收一个类型为T的参数,并返回一个类型为R的结果。
示例:使用 Function 接收参数并返回结果
import java.util.function.Function;
public class FunctionExample {
public static void main(String[] args) {
// 定义一个 Function:接收一个字符串并返回它的长度
Function<String, Integer> lengthFunction = str -> str.length();
// 调用 apply() 方法传递参数并获取结果
System.out.println(lengthFunction.apply("Hello")); // 输出 5
}
}
T:输入参数的类型。R:返回值的类型。apply(T t):方法用于接收输入参数并返回结果。
2. BiFunction<T, U, R>:接收两个参数并返回一个结果
- 定义:
BiFunction<T, U, R>接收两个参数,T和U,并返回一个类型为R的结果。
示例:使用 BiFunction 接收两个参数并返回结果
import java.util.function.BiFunction;
public class BiFunctionExample {
public static void main(String[] args) {
// 定义一个 BiFunction:接收两个整数并返回它们的乘积
BiFunction<Integer, Integer, Integer> multiplyFunction = (a, b) -> a * b;
// 调用 apply() 方法传递两个参数并获取结果
System.out.println(multiplyFunction.apply(5, 3)); // 输出 15
}
}
T:第一个输入参数的类型。U:第二个输入参数的类型。R:返回值的类型。apply(T t, U u):方法用于接收两个输入参数并返回结果。
3. Consumer<T>:接收一个参数但不返回结果
- 定义:
Consumer<T>接收一个类型为T的参数,但不返回任何结果(类似于void方法)。
示例:使用 Consumer 接收参数但不返回结果
import java.util.function.Consumer;
public class ConsumerExample {
public static void main(String[] args) {
// 定义一个 Consumer:接收一个字符串并打印出来
Consumer<String> printConsumer = str -> System.out.println(str);
// 调用 accept() 方法传递参数
printConsumer.accept("Hello, World!"); // 输出 "Hello, World!"
}
}
T:输入参数的类型。accept(T t):方法用于接收输入参数,不返回结果。
4. BiConsumer<T, U>:接收两个参数但不返回结果
- 定义:
BiConsumer<T, U>接收两个类型的参数,但不返回结果。
示例:使用 BiConsumer 接收两个参数但不返回结果
import java.util.function.BiConsumer;
public class BiConsumerExample {
public static void main(String[] args) {
// 定义一个 BiConsumer:接收两个参数并打印
BiConsumer<String, Integer> printConsumer = (name, age) ->
System.out.println(name + " is " + age + " years old");
// 调用 accept() 方法传递两个参数
printConsumer.accept("Alice", 25); // 输出 "Alice is 25 years old"
}
}
总结:
Supplier<T>:不接收任何参数,返回类型T的结果。Function<T, R>:接收一个参数,返回类型R的结果。BiFunction<T, U, R>:接收两个参数,返回类型R的结果。Consumer<T>:接收一个参数,不返回结果。BiConsumer<T, U>:接收两个参数,不返回结果。
根据需要选择合适的函数式接口来处理带参的场景。

浙公网安备 33010602011771号