Lambda表达式: 取代匿名内部类
小编在看见网上关于Lambda的解释有很多种,但是普遍不具有易读性,这里小编带着大家一起学习lambda表达式!小编根据CSDN上各种大佬的关于lambda的解释,其实总结起来也就是两句话:
1111111111111111111111111111111111111111111111111111
## 重要的事情说三遍!!!
Lambda表达式只和函数式接口有关!
Lambda表达式只和函数式接口有关!
Lambda表达式只和函数式接口有关!
## 重要的事情说三遍!!!
22222222222222222222222222222222222222222222
## 重要的事情再说三遍!!!
Lambda表达式 用于取代匿名内部类!
Lambda表达式 用于 取代匿名内部类!
Lambda表达式 用于取代匿名内部类!
## 重要的事情再说三遍!!!
所以首先我们一定要先明白什么是函数式接口:
函数式接口就是 :某个接口,里面有且仅有一个抽象方法.
然后我们一定要知道什么是匿名内部类:
点此了解什么是匿名内部类?
在知道函数式接口和匿名内部类之后,再结合之前小编强调三遍的内容就是lambda的所有内容了:
凡是需要使用匿名内部类且参数为函数式接口的方法,都可以使用Lambda表达式代替匿名内部类,
例如下面这个方法
// runnable
new Thread(new Runnable1() {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("C" + i);
}
}
}).start();
以上代码是一个线程的匿名内部类,里面的匿名内部类重写了父类Thread的run()方法,然后.start是运行该线程(对线程不熟悉的同学可以点这儿学习多线程),不过就算不会多线程也不影响对Lambda的掌握!!!,上面的代码在使用Lambda后变为:
new Thread(() -> {
for (int i = 0; i < 100; i++) {
System.out.println("C" + i);
}
}).start();
可以发现使用lambda后,代码省略了创建匿名内部类的步骤,直接写了方法体;
这里Lambda里面的小括号 () 里本应该填上参数列表的,但是由于run() 方法没有参数,故此时()里面什么也没填. ()后紧跟了一个箭头 - > 指向了右边写的方法体,这个方法体就是原本写在匿名内部类中的方法体
所以lambda的格式为: (参数列表) - > {方法体}
在以后写匿名内部类的地方,换上一个lambda简直不要太酷~~
例如现在假设有一个函数式接口A,里面有一个抽象方法methodA(int a, int b):
@Function
public interface A {
abstract void methodA(int a,int b);
}
然后我们在Test类中写一个main方法和一个methodTest(A a)方法注意此时methodTest()方法里面的参数列表是接口A:
普通使用匿名内部类的写法:
public class Test {
public void static methodTest(A a) {
// 我们在这儿调用a的methodA()方法,将10和20传进去
a.methodA(10,20);
}
// 为了让小伙伴们更好的理解lambda特意将主方法写在了下面
public static void main (String args[]) {
// 然后在这儿使用匿名内部类调用methodTest()
methodTest(new A(){
@Override
methodA (int a,int b) {
System.out.println("a+b="+(a+b));
}
});
}
}
上面代码的运行结果为: a+b=30
下面展示使用lambda后的效果:
public class Test {
public void static methodTest(A a) {
// 我们在这儿调用a的methodA()方法,将10和20传进去
a.methodA(10,20);
}
// 为了让小伙伴们更好的理解lambda特意将主方法写在了下面
public static void main (String[] args) {
// 然后在这儿使用匿名内部类调用methodTest()
methodTest((int a,int b) -> {
System.out.println("a+b="+(a+b));
});
}
}
上面代码的运行结果为: a+b=30
可以看见,在使用lambda表达式之后,代码简捷了太多太多,简直不要太酷!
然后给大家补充一下关于lambda的缩略写法:
- 如果函数式接口中的抽象方法参数列表的数据类型相同,则在写lambda的时候,小括号()中的参数可以省略参数类型,例如上例中的lambda还可以这样写:
methodTest((a,b) -> {
System.out.println("a+b="+(a+b));
});
- 如果函数式接口中的抽象方法参数列表只有一个参数,则在写lambda的时候可以在省略参数类型的情况下进一步省略小括号! 例如我们先创建一个函数式接口B,注意此时B中的抽象方法只有一个参数int a :
public interface B {
abstract void methodB(int b);
}
在Test类中写一个参数为B的方法method03(B b) ,并调用b 的methodB(int b)方法:
public static void method03(int b) {
b.method(100);
}
然后在main方法中调用methodTest03,并使用lambda表达式省略小括号()和参数类型:
methodTest03(x -> {
System.out.println("x="+(x));
});
结果为: x=100
- 如果函数式接口中的抽象方法体只有一条语句,则可以不写大括号!例如2例中的lambda还可以这样写:
methodTest03( x -> System.out.println(x) );
这就是Lambda表达式的一个简单应用方式了,下面小编再放几个Lambda关于List集合的代码给大家把玩一下叭~~~提一下噢,下面有很多关于Java8中Stream流的方法噢,两者结合,太酷了太酷啦!
// 创建一个list
List<String> list = Arrays.asList("a","b","c","d");
// 这里的Arrays.asList()方法可以将括号中的内容返回成一个list集合
// 普通迭代输出
for (String string : list) {
System.out.println("普通迭代"+string);
}
// Java8 Lambda表达式迭代输出:
list.forEach(x -> {System.out.println("lambda迭代:"+x);});
/*forEach()方法需要传入一个函数式接口类的参数(集合类型),
* 而此时lambda的作用就是一个"匿名内部类的取代方法"*/
// 静态方法引用迭代输出
list.forEach(System.out::println);
// 冒号冒号::叫做静态方法引用,也是Java8的新特性之一;
有关于Java8静态方法引用的内容小编也会在个人博客上做了介绍了,感兴趣的同学可以去看一看噢~~~
努力的人,祝你前程似锦呢!