Lambda表达式
Lambda表达式是 jdk1.8 引入的一个新特性,它是函数式编程在Java中的一种体现。
特点:
1. Lambda表达式的引入简化了匿名内部类的语法,让代码更加简洁。
2. Lambda表达式提供了一种便捷的语法形式,使得函数可以作为参数传递给方法,或者作为返回值返回。
3. Lambda表达式只能作用于函数式接口 (有且只有一个抽象方法的接口) 。
4. lambda表达式本质来讲,是一个匿名函数。
语法
1. (parameters) -> expression
2. (parameters) -> { statements;}
箭头(->)将参数与Lambda主体分隔开来。
参数部分:
1. 参数可以是任意合法的Java参数列表,可以为空或包含一个或多个参数;
2. 参数列表的类型名可以省略。 不能出现有些省略了,有些没有省略的情况;
3. 如果参数列表中,参数的数量有且只有一个,则小括号可以省略。
主体部分:
1. Lambda主体可以是一个表达式,表达式外的大括号,可加可不加。 没有大括号时,return关键字必须省略。
2. 也可以是一个代码块。将按照常规的Java语法执行,并且您可能需要使用return语句来返回值。
//无参数的Lambda表达式
()->System.out.println("无参数无返回值");
//有参数的Lambda表达式
(a)->System.out.println("有参数无返回值");
//多个参数的Lambda表达式
(a,b)->System.out.println(a+b);
//有返回值的Lambda表达式
(a,b)->{
return a+b;
}
变量的捕获
匿名内部类可以捕获外部变量,即在匿名内部类中引用并访问外部作用域的变量。这种行为称为变量捕获。
在匿名内部类中,可以捕获以下类型的变量:
1.实例变量:如果匿名内部类位于一个实例方法中,它可以捕获并访问该实例的实例变量。
2.静态变量:匿名内部类可以捕获并访问包含它的类的静态变量。
3.方法参数:匿名内部类可以捕获并访问包含它的方法的参数。
4.本地变量:匿名内部类可以捕获并访问声明为final的本地变量。final关键字可以省略,但该变量实际上必须是最终的。
Lambda表达式同样可以捕获外部作用域的变量。Lambda表达式可以捕获跟上述匿名内部类完全相同类型的变量。
public class Demo{
//实例变量
private int a;
//静态变量
private static int b;
static{
b= 2;
}
public Demo(){
a = 1;
}
public void m1(int c){
//局部变量
int d = 4;
//Lambda表达式
Test t = ()-> {
System.out.println("成员变量:"+a);
System.out.println("静态变量:"+b);
System.out.println("方法形参:"+c);
System.out.println("局部变量:"+d);
};
t.test();
}
public static void main(String[] args){
Demo d = new Demo();
d.m1(3);
}
interface Test{
void test();
}
Lambda表达式在集合中的应用
排序时
List<String> list = new ArrayList<>();
list.add("lily");
list.add("zeven");
list.add("coco");
list.add("peter");
//按照字符串的长度降序,比较器使用了Lambda表达式
Collections.sort(list,(a,b)->b.length()-a.length());
System.out.println(list);
迭代时
Integer[] arr = new Integer[]{4,5,10,6,3};
List<Integer> nums = Arrays.asList(arr);
//list迭代
nums.forEach(System.out::println);
//Set迭代
Set<Integer> set = new HashSet<>(nums);
set.forEach(System.out::println);
//Map迭代
Map<String,Integer> map = new HashMap<>();
map.put("张三",48);
map.put("李四",19);
map.put("王五",28);
map.put("赵六",30);
//key的迭代
map.keySet().forEach(Key->System.out.println(Key));
//values的迭代
map.values().forEach(v->System.out.println(v));
根据条件移除元素
List<Integer> nums = Arrays.asList(1,2,4,6,8,6);
List<Integer> nums2 = new ArrayList<>(nums);
nums2.removeIf(m-> m.equals(6));
System.out.println(nums2);
Lambda的优缺点
优点:
1.简洁性:Lambda表达式提供了一种更简洁、更紧凑的语法,可以减少冗余的代码和样板代码,使代码更易于理解和维护。
2.代码可读性:Lambda表达式使得代码更加自解释和易读,可以直接将逻辑集中在一起,提高代码的可读性和可维护性。
3.便于并行处理:Lambda表达式与Java 8引入的Stream API结合使用,可以方便地进行集合的并行处理,充分发挥多核处理器的优势,提高代码的执行效率。
4.避免匿名内部类的繁琐语法:相比于使用匿名内部类,Lambda表达式的语法更为简洁,减少了冗余的代码,提高了编码效率。
缺点:
1. 只能用于函数式接口:Lambda表达式只能用于函数式接口,这限制了它的使用范围
2. 可读性的折衷:尽管Lambda表达式可以提高代码的可读性,但在某些复杂的情况下,Lambda表达式可能变得难以理解和阅读,特别是当表达式变得过于复杂时。
3. 变量捕获的限制:Lambda表达式对捕获的变量有一些限制。它们只能引用final或实际上的最终变量,这可能对某些情况下的代码编写和调试带来一些困扰。