Function 是 Java 8 函数式接口,核心作用:接收一个参数,处理后返回一个结果(参数和返回值类型可以不同)。
简单理解:你给它一个原料,它加工完给你一个成品 → 有入参,有返回值。
一、核心定义
java
运行
@FunctionalInterface
public interface Function<T, R> {
// 唯一抽象方法:T=入参类型,R=返回值类型
R apply(T t);
}
- T:输入(参数)的类型
- R:输出(返回)的类型
- 核心方法:
R apply(T t) - 专门做:有参数、有返回值的转换 / 计算 / 处理
二、最基础用法(必看)
1. 匿名内部类(老式)
java
运行
import java.util.function.Function;
public class FunctionTest {
public static void main(String[] args) {
// 功能:接收 String,返回其长度 Integer
Function<String, Integer> fun = new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return s.length();
}
};
int len = fun.apply("Hello");
System.out.println(len); // 输出 5
}
}
2. Lambda 简化(推荐)
java
运行
public class FunctionTest {
public static void main(String[] args) {
// 字符串 → 长度
Function<String, Integer> getLength = s -> s.length();
int result = getLength.apply("Java Function");
System.out.println(result); // 输出 13
}
}
三、常用场景:类型转换、数据处理
示例 1:字符串转整数
java
运行
// String → Integer
Function<String, Integer> strToInt = s -> Integer.parseInt(s);
int num = strToInt.apply("100");
System.out.println(num + 1); // 101
示例 2:对象 → 某个属性(开发最常用)
java
运行
class User {
private String name;
private int age;
// 构造、getter
public User(String name, int age) { this.name = name; this.age = age; }
public String getName() { return name; }
}
// 使用:User → String(姓名)
Function<User, String> getUserName = user -> user.getName();
User user = new User("张三", 20);
String name = getUserName.apply(user);
System.out.println(name); // 张三
四、高级用法:链式调用(compose /andThen)
Function 支持多个函数串联执行,非常强大!
1. andThen:先执行当前,再执行下一个
java
运行
public class FunctionTest {
public static void main(String[] args) {
// f1:字符串 → 长度
Function<String, Integer> f1 = s -> s.length();
// f2:数字 → 平方
Function<Integer, Integer> f2 = i -> i * i;
// 先执行 f1,再执行 f2
Function<String, Integer> chain = f1.andThen(f2);
int result = chain.apply("Hello");
System.out.println(result); // 5² = 25
}
}
2. compose:先执行参数里的函数,再执行自己
java
运行
// f2.compose(f1) = 先 f1,再 f2
Function<String, Integer> chain2 = f2.compose(f1);
int result2 = chain2.apply("Hello"); // 同样 25
五、实战:封装通用工具方法
把 Function 当参数传入,实现通用数据提取 / 转换,代码极度灵活!
java
运行
public class FunctionTest {
// 通用工具:传入数据 + 转换规则,返回转换后的结果
public static <T, R> R convert(T data, Function<T, R> function) {
return function.apply(data);
}
public static void main(String[] args) {
User user = new User("李四", 25);
// 提取姓名
String name = convert(user, u -> u.getName());
System.out.println("姓名:" + name);
// 提取年龄
int age = convert(user, u -> u.getAge());
System.out.println("年龄:" + age);
// 自定义转换:年龄+10
int newAge = convert(user, u -> u.getAge() + 10);
System.out.println("新年龄:" + newAge);
}
}
六、扩展:BiFunction(两个参数)
如果需要接收两个参数,用 BiFunction<T, U, R>:
- T:参数 1
- U:参数 2
- R:返回值
java
运行
import java.util.function.BiFunction;
public class FunctionTest {
public static void main(String[] args) {
// 两个 int → 求和
BiFunction<Integer, Integer, Integer> add = (a, b) -> a + b;
int sum = add.apply(10, 20);
System.out.println(sum); // 30
}
}
七、Stream 中最常用(开发必备)
Stream.map() 方法的参数就是 Function!
java
运行
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class FunctionTest {
public static void main(String[] args) {
List<User> userList = Arrays.asList(
new User("小明", 20),
new User("小红", 18)
);
// map(Function):提取所有姓名
List<String> nameList = userList.stream()
.map(user -> user.getName()) // Function<User, String>
.collect(Collectors.toList());
System.out.println(nameList); // [小明, 小红]
}
}
八、Function vs Consumer(必区分)
表格
| 接口 | 入参 | 返回值 | 用途 |
|---|---|---|---|
| Function | 1 个 | 有 | 转换、计算、提取、处理 |
| Consumer | 1 个 | 无 | 打印、修改、消费、执行 |
一句话区分:
- 需要返回结果 → 用 Function
- 不需要返回结果 → 用 Consumer