Lambda 表达式
四种方式
定义
/**
定义函数接口
- 必须只有一个强制实现的方法
- 使用 @FunctionalInterface 标记该接口, 以在编译期检查是否有错误
- 可以有一个或多个默认方法
@FunctionalInterface
public interface ICalculator {
int square(int i);
}
一个参数
一个参数的时候不需要使用()
@Test
public void test() {
ICalculator ic = i -> i * i;
int res = ic.square(2);
System.out.println(res);
}
多个参数
多个参数时需要使用()
@Test
public void test2() {
IAddCalculator add = (a, b) -> a + b;
int res = add.add(1, 2);
System.out.println(res);
}
需要参数类型
有时需要指定参数类型,需要使用()
@Test
public void test3() {
IAddCalculator ia = (int a, int b) -> a + b;
int res = ia.add(1, 2);
System.out.println(res);
}
多行
当代码不止一行时,需要使用{}
@Test
public void test4() {
IAddCalculator ia = (a, b) -> {
int c = a + b;
return c + a + b;
};
int res = ia.add(1, 2);
System.out.println(res);
}
函数接口
自己定义
现在有如下代码, 一个函数接口, 已经一个使用改函数接口的类User
@FunctionalInterface
public interface SayHello {
String sayHi(String username);
}
public class User {
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String sayHello(SayHello sayHello) {
return sayHello.sayHi(this.username);
}
}
测试代码如下
@org.junit.Test
public void test() {
User user = new User();
user.setUsername("lisi");
String hi = user.sayHello(username -> "hello " + username);
System.out.println(hi);
}
内置函数接口
上面的代码,核心代码是user.sayHello(username -> "hello " + username);
。而为了这一行代码创建一个函数接口有点多此一举。
为了处理这种情况, JDK8提供了函数接口,可以帮我们简化上面的代码
public class Person {
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String sayHello(Function<String,String> sayHello){
return sayHello.apply(username);
}
}
@org.junit.Test
public void test2() {
Person zs = new Person();
zs.setUsername("zhang san");
String s = zs.sayHello(username -> "你好 " + username);
System.out.println(s);
}
Person 中的sayHello方法使用了一个Function<String,String>来替代我们自己的函数接口。第一个泛型参数表示输入的参数类型,第二个泛型参数表示输出的参数类型。
其他内置
接口 输入参数 返回类型 说明
UnaryOperator T T 一元函数,输入输出类型相同
Predicate T boolean 断言
Consumer T / 消费一个数据,只有输入没有输出
Function<T,R> T R 输入 T 返回 R,有输入也有输出
Supplier / T 提供一个数据,没有输入只有输出
BiFunction<T,U,R> (T,U) R 两个输入参数
BiPredicate<L, R> (L,R) boolean 两个输入参数
BiConsumer<T, U> (T,U) void 两个输入参数
BinaryOperator (T,T) T 二元函数,输入输出类型相同
方法引用
是什么
方法引用时lambda的一个表达式, 操作符是::
静态引用
当函数接口中只是调用一个静态方法时,采用方法调用的方式可以简化代码
@Test
public void test() {
Function<Integer, String> convert = String::valueOf;
String res = convert.apply(new Integer(1234));
System.out.println(res);
}
@Test
public void test2() {
Consumer<Integer> consumer = System.out::println;
consumer.accept(new Integer("2234"));
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义