前言:
🌟🌟本期讲解关于Lambda表达式,希望能帮到屏幕前的你。
🌈上期博客在这里:http://t.csdnimg.cn/o8CCD
🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客
目录
📚️1.Lambda表达式
1.1背景
lambda表达式允许你通过表达式来代替功能接口。 lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块),Lambda 表达式(Lambda expression),基于数学中的λ演算得名,也可称为闭包(Closure) 。
1.2语法
基本语法: (parameters) -> expression 或 (parameters) ->{ statements; }
1. paramaters:类似方法中的形参列表,这里的参数是函数式接口里的参数。
2. ->:可理解为“被用于”的意思
3. 方法体(statements):可以是表达式也可以代码块,是函数式接口里方法的实现。
// 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)
1.3函数式接口
要了解Lambda表达式,首先需要了解什么是函数式接口,函数式接口定义:一个接口有且只有一个抽象方法 。
注意:
1. 如果一个接口只有一个抽象方法,那么该接口就是一个函数式接口
2. 如果我们在某个接口上声明了 @FunctionalInterface 注解,那么编译器就会按照函数式接口的定义来要求该接口,这样如果有两个抽象方法,程序编译就会报错的。
代码实例如下:
@FunctionalInterface
interface NoParameterNoReturn {
void test();
default void test2() {
System.out.println("JDK1.8新特性,default默认方法可以有具体的实现");
}
}
注意:在判断是否只有一个抽象方法时,可以加入接口声明进行判断。
📚️2.Lambda表达式的基本使用
2.1使用方法
我们在上面提到过,Lambda可以理解为:Lambda就是匿名内部类的简化,实际上是创建了一个类,实现了接口,重写了接口的方法 。
具体代码如下:
public class testDemo {
public static void main(String[] args) {
NoParameterNoReturn noParameterNoReturn=()->{
System.out.println("hello world");};
noParameterNoReturn.test();
OneParameterReturn oneParameterReturn=( int a)->{
System.out.println("有返回值一个参数");
return a;};
int ret=oneParameterReturn.test(12);
System.out.println(ret);
}
}
//无返回值无参数
@FunctionalInterface
interface NoParameterNoReturn {
void test();
}
//有返回值一个参数
@FunctionalInterface
interface OneParameterReturn {
int test(int a);
}
注意:首先要准备好接口,只能有一个抽象方法,并且要根据要求设置返回类型,然后根据Lambda表达式的语法进行编写。
2.2语法简化
1. 参数类型可以省略,如果需要省略,每个参数的类型都要省略
3. 如果方法体当中只有一句代码,那么大括号可以省略。
2. 参数的小括号里面只有一个参数,那么小括号可以省略
4. 如果方法体中只有一条语句,且是return语句,那么大括号可以省略,且去掉return关键字。
📚️3.Lambda的变量捕获
3.1匿名内部类的变量捕获
代码如下:
class Test {
public void func(){
System.out.println("func()");
}
}
public class TestDemo {
public static void main(String[] args) {
int a = 100;
new Test(){
@Override
public void func() {
System.out.println("我是内部类,且重写了func这个方法!");
System.out.println("我是捕获到变量 a == "+a
+" 我是一个常量,或者是一个没有改变过值的变量!");
}
};
}
}
注意:在上述代码当中的变量a就是,捕获的变量。这个变量要么是被final修饰,如果不是被final修饰的 你要保证在使用 之前,没有修改。
3.2Lambda的变量捕获
和上述的匿名内部类的使用其实差不多,如下代码所示:
public class testDemo {
public static void main(String[] args) {
int b =100;
NoParameterNoReturn noParameterNoReturn = () -> {
System.out.println("hello world");
System.out.println(b);
};
noParameterNoReturn.test();
这里小编省略了申明的接口,所以要注意哦。
这里进行了对变量b的捕获,但是如果在方法体内进行改变变量的值,就会发生报错!!!
如下代码所示:
public static void main(String[] args) {
int b =100;
NoParameterNoReturn noParameterNoReturn = () -> {
System.out.println("hello world");
b=22;
System.out.println(b);
};
noParameterNoReturn.test();
此时就会发生报错:
📚️4. Lambda在集合当中的使用
为了能够让Lambda和Java的集合类集更好的一起使用,集合当中,也新增了部分接口,以便与Lambda表达式对接。
接口 |
方法
|
Collection
| removeIf() spliterator() stream() parallelStream() forEach() |
List
|
replaceAll()
sort()
|
Map
|
getOrDefault() forEach()
replaceAll() putIfAbsent() remove() replace() computeIfAbsent()
computeIfPresent() compute() merge()
|
4.1collection接口的使用
forEach() 方法演示
代码如下:
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("Hello");
list.add("bit");
list.add("hello");
list.add("lambda");
list.forEach(new Consumer<String>(){
@Override
public void accept(String str){
//简单遍历集合中的元素。
System.out.print(str+" ");
}
});
}
这里我们就可以使用Lambda表达式进行简写
代码如下:
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("Hello");
list.add("bit");
list.add("hello");
list.add("lambda");
//表示调用一个,不带有参数的方法,其执行花括号内的语句,为原来的函数体内容。
list.forEach(s -> {
System.out.println(s);
});
}
这样是不是大大简化了代码,使代码更加简洁呢~~~
4.2List接口的使用
sort方法的使用:
代码如下:
ArrayList<Integer> list = new ArrayList<>();
list.add(2);
list.add(1);
list.add(9);
list.add(8);
list.sort(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1-o2;
}
} );
System.out.println(list);
这里还能通过compareTo进行比较,这里通过源码解释,sort是通过比较器进行比较,这里list中的元素实现了comparable接口,能够使用compareto方法。
通过Lambda表达式的简化后:
ArrayList<Integer> list = new ArrayList<>();
list.add(2);
list.add(1);
list.add(9);
list.add(8);
list.sort((o1,o2)->o1.compareTo(o2));
System.out.println(list);
这样也大大简化了代码,让代码更加简洁。
4.3Map接口的使用
HashMap的foreach;
这里小编就将两种写法都在一个代码中进行演示:
public static void main(String[] args) {
HashMap<String,Integer> map = new HashMap<>();
map.put("hello",3);
map.put("abc",5);
map.put("def",2);
/*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));
注意:在HashMap中有两个参数,所以在编写Lambda表达式时要写两个参数,这里的灰色部分为不使用Lambda表达式的部分。
4.4.Lambda表达式的优缺点
Lambda表达式的优点很明显,在代码层次上来说,使代码变得非常的简洁。缺点也很明显,代码不易读。
优点:
1. 代码简洁,开发迅速
2. 方便函数式编程
3. 非常容易进行并行计算
4. Java 引入 Lambda,改善了集合操作
缺点:
1. 代码可读性变差
2. 在非并行计算中,很多计算未必有传统的 for 性能要高
3. 不容易进行调试
📚️5.总结
💬💬本期小编讲解了关于Lambda表达式的运用,关于它的语法,背景,基本使用,变量捕获,以及在集合当中的使用都有涉及,并且附加代码进行演示。
🌅🌅🌅~~~~最后希望与诸君共勉,共同进步!!!
💪💪💪以上就是本期内容了, 感兴趣的话,就关注小编吧。
😊😊 期待你的关注~~~