目录
1. 基本概念
2. 基本语法
3. 函数式接口
4. Lambda表达式的基本使用
4.1 语法精简
5. 变量捕获
6. Lambda在集合当中的使用
1. 基本概念
Lambda表达式是Java SE 8中一个重要的新特性。lambda表达式允许你通过表达式来代替功能接口。 lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)。
2. 基本语法
基本语法: (parameters) -> expression 或 (parameters) ->{ statements; }
Lambda表达式由三部分组成:
1. paramaters:类似方法中的形参列表,这里的参数是函数式接口里的参数。这里的参数类型可以明确的声明也可不声明而由JVM隐含的推断。另外当只有一个推断类型时可以省略掉圆括号。
2. ->:可理解为“被用于”的意思
3. 方法体:可以是表达式也可以代码块,是函数式接口里方法的实现。代码块可返回一个值或者什么都不返回,这里的代码块块等同于方法的方法体。如果是表达式,也可以返回一个值或者什么都不返回。
// 1. 不需要参数,返回值为 2
() -> 2
// 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x
// 3. 接受2个参数(数字),并返回他们的和
(x, y) -> x + y
// 4. 接收2个int型整数,返回他们的乘积
(int x, int y) -> x * y
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)
3. 函数式接口
要了解Lambda表达式,首先需要了解什么是函数式接口,函数式接口定义:一个接口有且只有一个抽象方法 。
注意:
1. 如果一个接口只有一个抽象方法,那么该接口就是一个函数式接口
2. 如果我们在某个接口上声明了 @FunctionalInterface 注解,那么编译器就会按照函数式接口的定义来要求该接
口,这样如果有两个抽象方法,程序编译就会报错的。所以,从某种意义上来说,只要你保证你的接口中只
有一个抽象方法,你可以不加这个注解。加上就会自动进行检测的。
定义的方式
@FunctionalInterface
interface NoParameterNoReturn {
//注意:只能有一个方法
void test();
}
回顾:这里简要回顾一下抽象方法和抽象类以及接口中的下相关知识
抽象方法:
java中的抽象方法就是以abstract修饰的方法,这种方法只声明返回的数据类型、方法名称和所需的参数,没有方法体,也就是说抽象方法只需要声明而不需要实现。
抽象方法与抽象类:
当一个方法为抽象方法时,意味着这个方法应该被子类的方法所重写,否则其子类的该方法仍然是abstract的,这个子类由于继承父类,拥有抽象方法,因此它也是抽象类,即声明为abstract。abstract抽象类不能用new实例化对象,abstract方法只允许声明不能实现。如果一个类中含有abstract方法,那么这个类必须用abstract来修饰,当然abstract类也可以没有abstract方法。 一个抽象类里面没有一个抽象方法可用来禁止产生这种类的对象。
抽象方法与接口:
在interface中所有的方法都是public abstract的,即使你没有声明它是public abstract的。在interface中所有的数据成员都是public static final的,即使你没有声明.但不能是blank final 在编译时候确定的。在java中,interface的地位和class是一样的。实现interface的类,其interface中所有的方法必须被“实现”,否则这个类成为一个抽象类。Interface可以从多个interface得到继承,但是不能继承类。一个类可以实现多个interface。
回到正题
lambda表达式在jdk1.8有了新的特性,可以有静态成员方法和默认的方法
4. Lambda表达式的基本使用
1.首先定义了六个接口(并且是函数式接口)
2. 使用lambda表达式使用这些接口
public class test {
public static void main1(String[] args) {
NoParameterNoReturn noParameterReturn = new NoParameterNoReturn() {
//1. 正常情况下使用接口,需要重写接口的方法
@Override
public void test() {
System.out.println("hello");
}
};
}
public static void main(String[] args) {
//1.此时为没有参数没有返回值的lambda表达式
NoParameterNoReturn noParameterNoReturn = ()->{System.out.println("hello");};
noParameterNoReturn.test();
//2.含有一个参数,没有返回值的lambda表达式
// 此时可以省略括号与参数类型 还有大括号
OneParameterNoReturn oneParameterNoReturn = (int x)->{System.out.println(x+10);};
oneParameterNoReturn.test(10);
//3.含有多个参数,没有返回值的lambda表达式
// 不能省略括号,类型不能单独省略,只能同时省略
MoreParameterNoReturn moreParameterNoReturn = (int x, int y)->{
System.out.println(x+y);
};
moreParameterNoReturn.test(1,2);
//4.没有参数有返回值
// 此时可以省略return
NoParameterReturn noParameterReturn = ()->{return 10;};
int ret1 = noParameterReturn.test();
System.out.println(ret1);
//5.一个参数有返回值
// 能省略括号;可以省略return
OneParameterReturn oneParameterReturn = (x)->{return x;};
int ret2 = oneParameterReturn.test(10);
System.out.println(ret2);
//6.一个参数有返回值
// 不能省略括号;可以省略return
MoreParameterReturn moreParameterReturn = (int x, int y)->{return x*y;};
MoreParameterReturn moreParameterReturn2 = (x, y)->x * y;;
int ret3 = moreParameterReturn.test(10,20);
System.out.println(ret3);
}
}
运行结果:
4.1 语法精简
1. 参数类型可以省略,如果需要省略,每个参数的类型都要省略。
2. 参数的小括号里面只有一个参数,那么小括号可以省略
3. 如果方法体当中只有一句代码,那么大括号可以省略
4. 如果方法体中只有一条语句,且是return语句,那么大括号可以省略,且去掉return关键字。
5. 变量捕获
1. 匿名内部类简单使用
2. 匿名内部类的变量捕获
在上述代码当中的变量a就是,捕获的变量。这个变量要么是被final修饰,如果不是被final修饰的 你要保证在使用之前,没有修改。
3. Lambda的变量捕获
6. Lambda在集合当中的使用
1.List接口
1.1sort()方法的演示
该方法根据c指定的比较规则对容器元素进行排序。
运行结果:
1.2 forEach
运行结果
2. map
forEach
此处就是与Sort重写的方法不相同,看源码为:
那么就需要重写accept函数,进行使用lambda表达式