文章目录
- Lambda表达式
- 一、语法
- 1.(parameters)
- 2. ->
- 3.方法体
- 4.函数式接口
- 二、Lambda的使用
- 三、变量捕获
- 四、Lambda在集合中的应用
Lambda表达式
- 允许通过Lambda表达式来代替功能接口
- 提供了一个正常的参数列表和使用这些参数的主体
- 也叫闭包
一、语法
(parameters) -> expression 或 (parameters) ->{ statements; }
1.(parameters)
1.这个参数的函数式接口中的参数
2.参数类型可以声明,也可以省略,让JVM来推断
3.只有一个推断类型时,可以省略掉( )
2. ->
- 指向符:“被用于”
3.方法体
1.可以是表达式,也可以是代码块。
2.是函数式接口里方法的实现
3.可以返回一个值或不返回
4.函数式接口
-
只有一个抽象方法的接口,叫做函数式接口
-
接口上声明 @FunctionalInterface 注解后,如果这个接口存在两个抽象方法,会报错
@FunctionalInterface
interface NoParameterNoReturn {
//函数式接口,只有一个抽象方法
void test();
default void func(){
System.out.println("func");
}
}
- 由于函数式接口只允许有一个抽象方法,因此其他非抽象方法(如equals、hashCode、toString等)都会被继承自Object类的默认实现覆盖。
- 在Java中,Object类中的equals方法是用来比较两个对象的内容是否相等,但默认实现是比较对象的引用是否相等。如果我们希望在函数式接口中重新定义equals方法,以实现内容相等的比较逻辑,就需要将equals方法声明为抽象方法,让具体实现类去覆盖默认的equals方法,从而实现我们所需的比较逻辑。
二、Lambda的使用
- 要调用的函数式接口
//无返回值无参数
@FunctionalInterface
interface NoParameterNoReturn {
void test();
}
//无返回值一个参数
@FunctionalInterface
interface OneParameterNoReturn {
void test(int a);
}
//无返回值多个参数
@FunctionalInterface
interface MoreParameterNoReturn {
void test(int a,int b);
}
//有返回值无参数
@FunctionalInterface
interface NoParameterReturn {
int test();
}
//有返回值一个参数
@FunctionalInterface
interface OneParameterReturn {
int test(int a);
}
//有返回值多参数
@FunctionalInterface
interface MoreParameterReturn {
int test(int a,int b);
}
- 如果不用Lambda表达式,则要用过匿名内部类来实现接口
NoParameterNoReturn noParameterNoReturn = new NoParameterNoReturn() {
//匿名内部列,实现了这个接口,重写了这个接口当中的方法
@Override
public void test() {
System.out.println("重写了test方法");
}
};//注意这里是分号
PriorityQueue<Integer>priorityQueue = new PriorityQueue<>(new Comparator<Integer>() {
//传进的是一个匿名对象
//这个类实现了这个接口并且重写了compare方法
@Override
public int compare(Integer o1, Integer o2) {
return 0;
}
});
- 而采用Lambda表达式,可以进行缩写
NoParameterNoReturn noParameterNoReturn = ()-> System.out.println("重写了test方法");
noParameterNoReturn.test();//重写了test方法
PriorityQueue<Integer>minHeap = new PriorityQueue<>((o1,o2)->{return o1.compareTo(o2);});
- 有无参数和有无返回值的各种接口实现Lambda写法
NoParameterNoReturn noParameterNoReturn = () -> System.out.println("重写了test方法");
noParameterNoReturn.test();//重写了test方法
OneParameterNoReturn oneParameterNoReturn = (a) -> System.out.println("oneParameterNoReturn" + a);
oneParameterNoReturn.test(10);//oneParameterNoReturn10
MoreParameterNoReturn moreParameterNoReturn = (a, b) -> System.out.println(a + b + "moreParameterNoReturn");
moreParameterNoReturn.test(1,3);
//有返回值
// NoParameterReturn noParameterReturn = ()->{return 10};
NoParameterReturn noParameterReturn = ()-> 10;
System.out.println(noParameterReturn.test());//10
OneParameterReturn oneParameterReturn = a -> a+1;
System.out.println(oneParameterReturn.test(2));//3
MoreParameterReturn moreParameterReturn = (a,b)->a+b;
System.out.println(moreParameterReturn.test(2, 3));//5
- Lambda表达式可读性差
- 可以省略掉参数类型
- 只有一个参数可以省略掉()
- 只有一条语句可以省略掉 { }
- 只有一条语句并且是return语句,可以省略掉return
三、变量捕获
匿名内部类的变量捕获
int a = 10;
//匿名内部类
NoParameterNoReturn noParameterNoReturn = new NoParameterNoReturn() {
//匿名内部列,实现了这个接口,重写了这个接口当中的方法
@Override
public void test() {
//a = 99;//会发生报错
System.out.println("重写了test方法");
}
};//注意这里是分号
- 在匿名内部类当中,如果要使用外部的变量需要满足一下条件
- 要么是常量、要么是未经修改的
- 总之,这个变量是不能修改的
在Lambda表达式中同理
int size = 10;
size = 100;
NoParameterNoReturn noParameterNoReturn = () -> System.out.println("重写了test方法"+size);
//报错,不能对变量进行修改
四、Lambda在集合中的应用
public static void main(String[] args) {
List<String>list = new ArrayList<>();
list.add("hello");
list.add("world");
list.add("!!!");
list.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
list.forEach(s -> System.out.println(s));
//简化
/* list.sort(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});*/
list.sort((o1, o2) -> o1.compareTo(o2));
list.forEach(s -> System.out.println(s));
}
-
forEach方法,继承自Consumer,是一个函数式接口
Map<String,Integer> map = new HashMap<>();
map.put("hello",1);
map.put("world",2);
map.put("!!!",3);
/* map.forEach(new BiConsumer<String, Integer>() {
@Override
public void accept(String s, Integer integer) {
System.out.println("key = "+s+" val = "+integer);
}
});*/
map.forEach((key,val)-> System.out.println("key = "+key+" val = "+val));
点击移步博客主页,欢迎光临~