ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
## Lambda编程 在前面的章节中,我们讲解过如何使用匿名内部类,虽然匿名内部类的代码相比常规的类要简洁,但**如果匿名内部类只包含一个方法,那么匿名内部类的语法就显得有些冗余**。为此,在JDK 1.8中,引入了Lambda表达式。 * **高阶函数:当Lambda表达式以函数的实际参数或者返回值存在时,该函数被称为高阶函数**; * **内联函数:当Lambda表达式被inline修饰时,该函数被称为内联函数**。 ### Lambda表达式入门 Lambda表达式由数学中的λ演算得名,它是**一个匿名函数,是对匿名内部类的一种简化**,本小节中我们将针对Lambda表达式进行详细讲解。 #### Lambda表达式简介 Lambda表达式就是一个匿名函数,它是函数式编程的基础,所谓函数式编程实际上就是一种编程范式,即如何编写程序的方法论。函数式编程的思想是将计算机运算视为函数的计算,并且计算的函数可以接收函数作为输入参数或者当作返回值来使用。使用函数式编程可以减少代码的重复,提高程序的开发效率。 Lambda表达式相对于普通函数有些区别,普通函数有4种返回值类型,即无参数无返回值、无参数有返回值、有参数无返回值、有参数有返回值。而**Lambda表达式只有两种返回值类型,即无参数有返回值、有参数有返回值**。 ##### 无参数有返回值 在定义无参数有返回值的Lambda表达式时,**只需要将函数体写在“{}”中,函数体可以是表达式或语句块**,具体语法格式如下: ``` {函数体} ``` 例 ``` {println()} ``` 上面这行代码就是**声明一个无参数有返回值的Lambda表达式,相当于声明了一个函数**。 下面我们就来学习一下如何调用无参数有返回值的Lambda表达式。 无参数有返回值的Lambda表达式调用的语法格式如下: ``` {函数体}() ``` 例 ``` {println()}() ``` 从上述代码可以看出,**在调用Lambda表达式时,只是在Lambda表达式后添加了“()”,“()”就代表了调用该表达式。当Lambda表达式被调用之后便会执行表达式中的函数体。** 接下来我们通过一个简单的案例来进行Lambda表达式的调用,具体代码如下所示。 ``` fun main(args: Array<String>) { { println("Lambda表达式无参数有返回值") //这一行就是函数体 }() } ``` 运行结果: ``` Lambda表达式无参数有返回值 ``` ##### 有参数有返回值 在定义有参数有返回值的Lambda表达式时,需**要指定参数名称以及参数类型,参数之间使用英文“,”分隔,且参数类型可以省略,函数体会自动校对。Lambda表达式中的“->”用于表示箭头,用于指定参数或数据的指向**,具体语法格式如下: ``` {参数名:参数类型,参数名:参数类型…->函数体} ``` 有参数有返回值的Lambda表达式与无参数有返回值的Lambda表达式**调用方式基本类似**,同样**需要在表达式后方添加“()”,只不过“()”中需要填写函数的参数**,有参数有返回值的Lambda表达式调用的语法格式如下: ``` {参数名:参数类型,参数名:参数类型 … -> 函数体} (实参1,实参2,...) ``` 接下来我们通过一个案例来进行演示,具体代码如下所示。 ``` fun main(args: Array<String>) { val sum = { a : Int,b : Int -> a + b }(6,8) print(sum) } ``` 运行结果: ``` 14 ``` 在上述代码中,定义了一个函数,并将该函数赋值给变量sum。在该函数中声明了两个Int类型的变量a和b,函数体中执行a和b的是求和操作,“->”后的a+b便是返回的结果。为了调用该函数,在函数体后方使用“(6,8)”传递了两个实参6和8,最后将结果进行打印,输出运行结果14。 在上面的示例中是在声明Lambda表达式之后直接就调用此函数,**在开发中还可以将Lambda表达式赋值给一个变量,通过变量来直接调用**。接下来我们来对前面的示例进行修改,修改后的代码如下所示。 ``` fun main(args: Array<String>) { var sum = { a : Int,b : Int -> a + b } println(sum(6,8)) //函数调用 } ``` 运行结果: ``` 14 ``` ##### Lambda表达式返回值 由于Lambda表达式所表示的函数都是有返回值的,但通过以上案例可知,Lambda表达式已经省略了返回值的类型和方法名,那么是**如何来声明返回值的类型和返回值**的呢?接下来我们通过一个案例来演示,具体代码如下所示。 ``` fun main(args: Array<String>) { println("-------------------1----------------------") val result1 = { println("输出语句1"); "字符串" }() println("返回值:$result1") println("返回值类型:${result1.javaClass}") println("-------------------2----------------------") val result2 = { println("输出语句1"); println("输出语句2"); 18 }() println("返回值:$result2") println("返回值类型:${result2.javaClass}") println("------------------3-----------------------") val result3 = { println("输出语句1"); println("输出语句2"); true }() println("返回值:$result3") println("返回值类型:${result3.javaClass}") } ``` 运行结果: ``` -------------------1---------------------- 输出语句1 返回值:字符串 返回值类型:class java.lang.String -------------------2---------------------- 输出语句1 输出语句2返回值:18 返回值类型:int ------------------3----------------------- 输出语句1 输出语句2 返回值:true 返回值类型:boolean ``` 从运行结果可以看出,**在每次调用Lambda表达式时,不管方法体里面的语句执行多少条,返回值的类型和返回值都是由方法体中最后一条语句决定的,因此在实际返回值后不要编写任何语句**。 * **如果在实际返回值后编写语句会发生什么情况呢?** 接下来我们通过一个数字求和的案例来进行演示,具体代码如下所示。 ``` fun main(args: Array<String>) { var sum = { a :Int,b: Int -> a + b "我是捣乱的" } println(sum(9,7)) } ``` 运行结果: ``` 我是捣乱的 ``` 从运行结果可以看出,程序功能是求a与b两个数字之和,但是返回值却是“我是捣乱的”,与预期不符,无法输出想要的结果,所以此处一定要记住,**不要将不是返回值的语句放置在方法体的最后一条语句的位置**。