Lamda表达式
文章目录
- Lamda表达式
- 前言
- 一、Lambda基本概念
- 1.背景
- 2.Lambda表达式语法
- 3.Lambda表达式五种不同的形式
- 4.引用值,而不是变量
- 二、Lambda表达式使用方式
- 1.无参数无返回值
- 2.无参数有返回值
- 3.有参数无返回值
- 4.有参数有返回值
- 三、Lambda表达式变量作用域
- 四、集合中Lambda表达式的应用
前言
一、Lambda基本概念
1.背景
Java8的最大变化是引入了Lambda表达式,它是所有Java8特性内容的基础——一种紧凑的,传递行为的方式。lambda表达式允许你通过表达式来代替功能接口,lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体, Lambda 表达式(Lambda expression)可以看作是一个匿名函数,也称为闭包
2.Lambda表达式语法
基本语法: (parameters) -> expression 或 (parameters) ->{ statements; }
Lambda表达式由三部分组成:
parameters:参数,类似方法中的形参列表,这里的参数是函数式接口里的参数
->:可理解为“被用于”的意思
方法体:可以是表达式也可以代码块,是函数式接口里方法的实现。代码块可返回一个值或者什么都不反回,这里的代码块等同于方法的方法体。如果是表达式,也可以返回一个值或者什么都不返回
3.Lambda表达式五种不同的形式
//1、无需要参数,使用空括号()表示没有参数。
//该Lambda表达式实现了Runnable接口,该接口也只有一个run方法,没有参数,返回值类型为void
Runnable noArguments = () -> System.out.println("Hello World")
// 2. 接收一个参数,可以省略括号,返回其2倍的值
x -> 2 * x
//3. Lambda表达式主体不仅可以是表达式,也可以是一段代码块,使用大括号{}将代码括起来。
() ->{
System.out.println("Hello");
System.out.println("World")
}
//4.Lambda表达式可以包含多个参数的方法。接受2个参数(数字),并返回他们的和
(x,y)->x+y;
//5.声明是参数类型,也可以是多个参数。接收2个int型整数,返回他们的和
(int x,int y)->x+y;
4.引用值,而不是变量
Java8虽然放松了对非final变量的引用,但是该变量在既成事实上必须是final。虽然无需将变量声明为final,但是在lamdba表达式中,也无法用作非终态变量。不然编译器就会报错
既成事实上得final是指只能给该变量赋值一次,换句话说,lambda表达式引用得是值,而不是变量,如下:
1、name就是一个既成事实的final变量
private static void streamTest( List<PersonVO> list,PersonVO personVO) {
String name=personVO.getName();
list.stream().filter(e-> name.equals(e.getName())).collect(Collectors.toList());
}
2、下面试图给name重新赋值,然后在lanbda去引用它,编译器就会报错,提示该变量必须是一个final。
需要修改如下,重新定义一个finalName给lanbda使用
private static void streamTest( List<PersonVO> list,PersonVO personVO) {
String name=personVO.getName();
name="asda";
String finalName = name;
list.stream().filter(e-> finalName.equals(e.getName())).collect(Collectors.toList());
}
这种行为也解释了为什么Lambda表达式也被称为闭包,未赋值的变量与周围环境隔离起来,进而被绑定到一个特定的值
二、Lambda表达式使用方式
Lambda 表达式只能实现函数式接口,什么是函数式接口呢?就是一个接口有且只有一个抽象方法
1.无参数无返回值
() -> { System.out.println("无参数无返回值");}
2.无参数有返回值
() -> { return "无参数有返回值"}
3.有参数无返回值
1、一个参数
param ->{System.out.println("无参数无返回值")}
2、多个参数
(param1,param2)->{System.out.println("无参数无返回值")}
4.有参数有返回值
1、一个参数
param ->{return param}
2、多个参数
(param1,param2)-{return param1+param2}
代码示例如下:
public class DomeLambda {
interface NoParameterNoReturn {
// 无参数无返回值
void test();
}
interface OneParameterNoReturn {
// 一个参数无返回值
void test(String param);
}
interface TwoParameterNoReturn {
// 两个参数无返回值
void test(String param1, String param2);
}
interface NoParameterHasReturn {
// 无参数有返回值
String test();
}
interface OneParameterHasReturn {
// 无参数有返回值
String test(String param);
}
interface TwoParameterHasReturn {
// 无参数有返回值
String test(String param1,String param2);
}
public static void main(String[] args) {
//1、无参数无返回值
NoParameterNoReturn noParameterNoReturn = () -> {
System.out.println("无参数无返回值");
};
noParameterNoReturn.test();
//2、一个参数无返回值
OneParameterNoReturn oneParameterNoReturn= param ->{
System.out.println(param);
};
oneParameterNoReturn.test("一个参数无返回值");
//两个参数,无返回值
TwoParameterNoReturn twoParameterNoReturn = (param1,param2)->{
System.out.println(param1+param2);
};
twoParameterNoReturn.test("两个参数","无返回值");
//3、无参数有返回值
NoParameterHasReturn noParameterHasReturn =()->{
return "无参数有返回值";
};
System.out.println(noParameterHasReturn.test());
//4、有参数有返回值
OneParameterHasReturn parameterHasReturn =param ->{
return param;
};
System.out.println(parameterHasReturn.test("有参数有返回值"));
TwoParameterHasReturn twoParameterHasReturn=(param1, param2) ->{
return param1+param2;
};
System.out.println(twoParameterHasReturn.test("两个参数","有返回值"));
}
}
三、Lambda表达式变量作用域
前面说的Lambda表达式是引用值,而不是变量。Lambda 表达式中使用的局部变量可以不用声明为 final,但是必须不可被后面的代码修改,即隐性的具有 final 的语义。
public class DomeLambda {
interface TestScope {
void test();
}
public static void main(String[] args) {
// 定义一个局部变量,但是后面不能对该变量进行修改,不然就会编译报错,即前面隐形的定义final
String name ="test" ;
TestScope testScope =()->{
System.out.println("局部变量 age = " + name );
};
testScope.test();
}
四、集合中Lambda表达式的应用
在 Java 1.8 中给集合新增了很多方法,方法的参数类型是函数式接口,所以在使用这些方法时,可以大量使用 Lambda 表达式,让我们的代码更简洁紧凑。
接口 | 新增方法 |
Iterable | default void forEach(Consumer<? super T> action) |
Collection | default boolean removeIf(Predicate<? super E> filter) |
List | default void sort(Comparator<? super E> c) |
default void replaceAll(UnaryOperator operator) | |
Map | comparingByKey(Comparator<? super K> cmp) |
comparingByValue(Comparator<? super V> cmp) | |
default void forEach(BiConsumer<? super K, ? super V> action) | |
default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) | |
default V merge(K key, V value,BiFunction<? super V, ? super V, ? extends V> remappingFunction) | |