– 面向过程程序语言:参数传递是基本类型的变量
– 面向对象语言:
- 传递基本类型的变量
- 传递对象变量
– 函数式程序语言设计:传递方法 / 代码块
即允许把函数作为一个方法的参数(函数作为参数传递进方法中)–>> Lambda 表达式–> Java 8 发布的新特性,引入了一个新的操作符 " -> " 该操作符称为箭头操作符或 Lambda 操作符
使用 Lambda 表达式可以使代码变的更加简洁紧凑。
lambda 表达式的语法格式:
- 参数,箭头,一个表达式
(parameters) -> expression
- 参数,箭头,{多个语句}
(parameters) ->{ statements; }
lambda表达式的重要特征:
- 类似匿名方法,一个没有名字的方法
- 不需要声明参数类型,编译器可以统一识别参数值
- 坚决不声明返回值类型
- 没有 public/protected/private/static/final 等修饰符
- 单句表达式,将直接返回值,不用大括号
- 带 return 语句, 算多句,必须用大括号(不用void()声明)
如果有返回值,返回值类型会在上下文推断出来的,无需声明,只在某几个分支有返回值,是不合法的
x ->
{
if(x>0)
return x+1;
};
数组字符串排序实例
package com.lambda;
import java.util.Arrays;
//doc:StringOrderTest.java
public class StringOrderTest {
public static void main(String[] args) {
String[] planets = new String[] {
"Mercury", "Venus", "Earth", "Mars",
"Jupiter", "Saturn", "Uranus","Neptune" };
System.out.println(Arrays.toString(planets)); //返回指定数组的内容的字符串表示形式
System.out.println("=======================");
System.out.println("使用长度从小到大的比较器:");
Arrays.sort(planets, new LengthAscComparator()); //按照数字顺序排列指定的数组
System.out.println(Arrays.toString(planets));
System.out.println("使用长度从大到小的比较器:");
Arrays.sort(planets, new LengthDescComparator());
System.out.println(Arrays.toString(planets));
System.out.println("=======================");
System.out.println("使用Lambda, 长度从小到大:");
Arrays.sort(planets,
(String first, String second)
-> first.length() - second.length());
System.out.println(Arrays.toString(planets));
System.out.println("使用Lambda, 长度从大到小:");
Arrays.sort(planets, (first, second) -> (-1) * (first.length() - second.length()));
System.out.println(Arrays.toString(planets));
System.out.println("使用Lambda, 长度从大到小:");
Arrays.sort(planets,
(String first, String second) -> {
int result = (-1) * (first.length() - second.length());
return result;
}
);
System.out.println(Arrays.toString(planets));
System.out.println("=======================");
//无参数,仅保留括号,箭头和表达式
new Thread(
() -> {
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum = sum + i;
}
System.out.println("总和:" + sum);
}
).start();
}
}
package com.lambda;
import java.util.Comparator; //比较器,Comparator接口实现自定义排序
//doc:LengthAscComparator.java
public class LengthAscComparator implements Comparator<String> {
public int compare(String first, String second) {
//获取2个字符串长度
int len1 = (first==null? 0 : first.length());
int len2 = (first==null? 0 : second.length());
//如果len1 == len2,返回0,表示两个字符串相等
//如果len1 > len2,返回正数,表示first>second
//如果len1 < len2,返回负数,表示first<second
return len1 - len2;
}
}
package com.lambda;
import java.util.Comparator;
//doc:LengthDescComparator.java
public class LengthDescComparator implements Comparator<String> {
public int compare(String first, String second) {
//获取2个字符串长度
int len1 = (first==null? 0 : first.length());
int len2 = (first==null? 0 : second.length());
//如果len1 == len2,返回0,表示两个字符串相等
//如果len1 > len2,返回正数,表示first>second
//如果len1 < len2,返回负数,表示first<second
return (-1) * (len1 - len2);
}
}
运行结果:
函数式接口 (Functional Interface)
- 只包含一个抽象方法的接口
- 可以包括其他的 default 方法、 static 方法、 private 方法
- 由于只有一个未实现的方法,所以 Lambda 表达式可以自动填上这个尚未实现的方法
- 采用 Lambda 表达式,可以自动创建出一个( ( 伪) ) 嵌套类的对象( ( 没有实际的嵌套类 class 文件产生) ),然后使用,比真正嵌套类 更加轻量 ,更加简洁高效
上例中 - - >> Lambda 表达式( ( 匿名函数) ) 自动成为接口方法的实现
Lambda 表达式:自动填充上Comparator的compare方法,变成一个Comparator的子对象
若不用Lambda 表达式,可采用匿名内部类:相对不够简洁,还会产生额外的嵌套类的class文件(含$符号的文件)
java.utils包下的Comparator接口。该接口代表一个比较器,java数组工具类和集合工具类中提供对sort方法排序就是使用 Comparator接口来处理排序的。
Comparator接口中有一个方法int compare(T o1, T o2)。这个方法返回值是int类型,
如果返回值小于0,说明比较结果是o1<o2,
如果返回值等于0,说明比较结果是o1=o2,
如果返回值大于0,则说明比较结果是o1>o2。
自定义函数式接口时,可写上系统自带的函数式接口注解,用于编译器检查:
@FunctionalInterface
函数式接口的优缺点:
- 只带有一个未实现的方法,内容简单
- 大量重复性的函数式接口,使得源码膨胀
为避免源码膨胀,可采用系统自带的函数式接口
- 涵盖大部分常用的功能,可以重复使用
- 位于 java.util.function 包中
Java内置的四大函数式接口:
方法引用: Method Reference
Lambda 表达式支持传递现有的类库函数