JavaSE-29 Java8的Lambda表达式
概念说明
- Lambda表达式是Java8提供的新特性,支持将代码块作为方法的参数。
- Lambda表达式支持使用简洁的代码创建只有一个方法的接口(函数式接口)。
- 只包含一个方法的接口也称为函数式接口。
Lambda表达式示例
在命令模式的例子中(地址:http://www.cnblogs.com/rask/p/8309876.html),可以直接向业务处理类方法传入实际代码,有两种实现方式:局部匿名内部类和Lambda表达式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | public class Test { public static void main(String[] args) { DataProcess dp = new DataProcess(); int [] data = { 1 , 2 , - 10 , 9 , 18 }; // 使用局部内部类 dp.service(data, new ICommand() { @Override public void process( int [] data) { System.out.print( "数组data中的元素有:" ); for ( int item : data) { System.out.print(item + " " ); } } }); // 使用lambda表达式 dp.service(data, target -> { int sum = 0 ; for ( int i = 0 ; i < target.length; i++) { sum += data[i]; } System.out.println( "数组所有元素之和为:" + sum); }); } } |
Lambda表达式的主要作用:用于替换匿名内部类繁琐的语法。
Lambda表达式语法格式
1 | (参数类型 参数 1 ,参数类型,参数 2 )->{代码块} |
- 形参列表:允许省略形参参数类型。如果只有一个参数,圆括号也可以省略。
- “->” :使用英文的中画线和大于号表示。
- 代码块:如果代码块只有一条语句,可以省略"{}"。如果代码块只有一条return语句,return关键字也可以省略。
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | package com.etc.qs; /**函数式接口*/ @FunctionalInterface interface OneAble { void method(); } /**函数式接口*/ @FunctionalInterface interface TwoAble { void method(String str); } /**函数式接口*/ @FunctionalInterface interface ThreeAble { int method( int a, int b); } public class QSDemo { public void OneAbleImpl(OneAble oneAble) { System.out.println(oneAble.toString()); oneAble.method(); } public void TwoAbleImpl(TwoAble twoAble) { System.out.println(twoAble.toString()); twoAble.method( "Hello Lamda!" ); } public void ThreeAbleImpl(ThreeAble threeAble) { System.out.println( "10和15的和为:" + threeAble.method( 10 , 15 )); } public static void main(String[] args) { QSDemo q = new QSDemo(); // Lambda表达式代码块只有一条语句,可以省略"{}" q.OneAbleImpl(() -> System.out.println( "新年好!" )); // Lambda表达式的形参列表只有一个形参,可以省略"()" q.TwoAbleImpl(str -> { System.out.println(str); System.out.println( "执行了一个参数的方法!" ); }); // Lambda表达式代码块只有一条语句,可以省略"{}",如果该条语句为带返回值,同时可以省略return关键字 q.ThreeAbleImpl((a, b) -> a + b); } } |
函数式接口
Lambda表达式的类型,也称为“目标类型”。Lambda表达式的目标类型必须是“函数式”接口(functional interface)。
函数式接口:只有一个抽象方法的接口。这种类型的接口也称为SAM接口,即Single Abstract Method interfaces。
Java8提供了函数式接口注解:
1 | @FunctionalInterface |
该注解用于编译时检查接口是否满足函数式接口规范。
总而言之,Lambda表达式使用限制归纳为以下两点:
- Lambda表达式目标类型必须是函数式接口。
- Lambda只能为函数式接口创建对象。
Lambda表达式方法引用和构造器引用
如果Lambda表达式代码块只有一条语句,可以在代码中使用方法引用和构造器引用,使用”::”进行引用。
引用方式汇总:
种类 | 引用示例 | 说明 | 对应Lambda表达式 |
引用类方法 | 类名::类方法 | 函数式接口中被实现方法的全部参数传给该类方法作为参数 | (a,b,...)->类名.类方法(a,b,...) |
引用特定对象的实例方法 | 特定对象::实例方法 | 函数式接口中被实现方法的全部参数传给该方法作为参数 | (a,b,...)->特定对象.实例方法(a,b,...) |
引用某类对象的实例方法 | 类名::实例方法 | 函数式接口中被实现方法的第一个参数作为调用者,后面的参数全部传给该方法作为参数 | (a,b,...)->a.实例方法(b,...) |
引用构造器 | 类名::new | 函数式接口中被实现方法的全部参数传给该构造器作为参数 | (a,b,...)->new 类名(a,b,...) |
表格数据来源:《疯狂java讲义》
引用类方法示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /** * 函数式接口 * 用于把字符串转换为整数 * */ @FunctionalInterface interface Converter{ Integer convert(String from); } public class MethodRef { public static void main(String[] args) { //Converter converter=(String from)->{return Integer.valueOf(from);}; Converter converter=Integer::valueOf; //引用类方法valueOf Integer val=converter.convert( "8899" ); System.out.println(val); } } |
引用特定对象的实例方法示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /** * 函数式接口1 * 判断字符串中是否包含指定字符 * */ @FunctionalInterface interface Converter1{ int convert(String from); } public class MethodRef { public static void main(String[] args) { Converter1 converter1= "etc.com" ::indexOf; //indexOf为String类的实例方法 int result=converter1.convert( "c" ); System.out.println(result); } } |
引用某类对象的实例方法示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /** * 函数式接口2 * 字符串截取 * */ @FunctionalInterface interface Converter2{ String convert(String from, int a, int b); } public class MethodRef { public static void main(String[] args) { Converter2 converter2=String::substring; //引用String类的实例方法 String result=converter2.convert( "etc.com" , 2 , 4 ); System.out.println(result); } } |
引用构造器示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | /**打开一个Frame窗体*/ @FunctionalInterface interface MyFrame { JFrame windows(String title); } public class MethodRef { public static void main(String[] args) { MyFrame mf=JFrame:: new ; //引用JFrame类的构造器 JFrame jf=mf.windows( "我的窗体" ); jf.setVisible( true ); jf.setSize( 400 , 400 ); } } |
本博客文章未经许可,禁止转载和商业用途!
如有疑问,请联系: 2083967667@qq.com
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· .NET 适配 HarmonyOS 进展
· 手把手教你更优雅的享受 DeepSeek
· 腾讯元宝接入 DeepSeek R1 模型,支持深度思考 + 联网搜索,好用不卡机!
· AI工具推荐:领先的开源 AI 代码助手——Continue
· 探秘Transformer系列之(2)---总体架构
· V-Control:一个基于 .NET MAUI 的开箱即用的UI组件库