lambda表达式允许你通过表达式代替功能接口。
lambda表达式可以看作是一个匿名函数,Lambda也称为闭包(Closure
)
基本语法:
(parameters)->expression
或(parameters)->(statements;)
- paramaters:类似方法中的形参列表,参数类型可以明确声明,也可以通过JVM推断得出,只有一个推断类型时可以省略圆括号。
- ->:被用于
- 方法体:可以是表达式或者代码块,是函数式接口里方法的实现,可以返回一个值或者什么都不返回。这里的代码块等同于方法的方法体。
0 lambda表达式底层解析运行原理
- Lambda表达式在编译的过程中会生成一个私有的静态方法,在静态方法中做了一个方法的基本实现。
- 另外在编译的同时会针对Lambda表达式的目标接口,生成一个内部类型实现定义的接口,在实现这个接口的方法中完成对这个静态方法具体执行过程的调用.
Ⅰ lambda表达式基本使用
import java.util.*;
有参数,无返回值
@FunctionalInterface
interface MoreParameter{
void test(int a,int b);
}
有参数,有返回值
@FunctionalInterface
interface MoreParameterHasReturn{
int test(int a);
}
public class Main{
public static void main(String[] args){
MoreParameter nop = (int a,int b)->{
System.out.println("hello"+a+b);
};
nop.test(2,3);
MoreParameterHasReturn hp = (int a)->{
System.out.println("hello"+a);
return a;
};
hp.test(9);
}
}
注意:
函数式接口:函数式接口有且只能有一个抽象方法。只要接口中出现多个抽象方法,那么就不能称之为函数式接口。@FunctionalInterface
注解,用来标识这是函数式接口。
(1) 当只有一个参数时,可以省略参数小括号:
MoreParameterHasReturn hp = a->{
System.out.println("hello"+a);
return a;
};
(2)如果方法体也只有一行代码,那么花括号也可以省略掉。
MoreParameter nop = (a,b)->
System.out.println("hello"+a+b);
变量捕获:lambda表达式中存在变量捕获。Java当中的匿名类中也存在变量捕获。
匿名内部类中的变量捕获:
import java.util.*;
class Test{
public void func(){
System.out.println("hello");
}
}
public class Main{
public static void main(String[] args){
int b=90;
new Test(){
@Override
public void func(){
System.out.println("hello.world"+b);
}
};
}
}
其中的变量b就是匿名内部类捕获到的变量。其中变量b必须是一个常量或者一个不会发生改变的量。
Ⅱ Lambda在集合中的使用
Collection
:
removeIf(), spliterator(),stream(),
parallelStream(),forEach()
List
:
replaceAll(),sort()
Map
:
getOrDefault(),forEach(),replaceAll(),
putIfAbsent(),remove(),replace(),
computeIfAbsent(),computerIfPresent(),
compute(),merge()
(1)List中
import java.util.*;
import java.util.function.Consumer;
public class Main{
public static void main(String[] args){
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.forEach(new Consumer<Integer>() {
@Override
public void accept(Integer integer) {
System.out.println(integer+" ");
}
});
list.forEach((integer)-> System.out.println(integer+" "));
list.sort(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});
list.sort((o1,o2)-> {return (o2-o1);});
System.out.println(list);
}
}
List中的forEach和sort方法中的参数都是一个函数式接口,所以可以用lambda表达式表示。
(2)Map中
import java.util.*;
import java.util.function.BiConsumer;
public class Main{
public static void main(String[] args){
HashMap<Integer,String> map = new HashMap<>();
map.put(1,"hao");
map.put(2,"buhao");
map.put(3,"zhennan");
map.forEach(new BiConsumer<Integer, String>() {
@Override
public void accept(Integer integer, String s) {
System.out.println(integer+"::"+s);
}
});
map.forEach((interger,s)->{
System.out.println(interger+"**"+s);
});
}
}
lambda表达式的优缺点:
优点:
- 代码简洁,开发迅速
- 方便函数式编程
- 非常容易进行并行计算
- 改善了集合操作
缺点:
- 代码可读性变差
- 在非并行计算中,未必有传统的for性能高.
- 不容易进行调试。