目录
lambda表达式介绍
java 8引入的lambda表达式可以简化我们的代码,它可以代替匿名内部类使用,lambda表达式本质上是一个匿名类。
lambda表达式的简单使用
下面是我们使用匿名内部类的形式实现一个接口:
public class Main {
public static void main(String[] args) {
//使用匿名内部类实现接口
Cal cal = new Cal(){
@Override
public int test(int a, int b){
return a + b;
}
};
System.out.println(cal.test(1, 2));
}
}
interface Cal{
//无参无返回类型
int test(int a, int b);
}
但如果我们使用lambda表达式就会是下面的形式:
public class Main {
public static void main(String[] args) {
//使用lambda表达式实现接口
Cal cal1 = (a, b) -> a + b;
System.out.println( cal1.test(1, 2));
}
}
interface Cal{
//加法方法
int test(int a, int b);
}
从上面我们可以看出,使用lambda表达式可以极大的简化我们的代码,但同样地也会带来阅读上的困难,下面我们来深入的学习一下lambda表达式。
lambda表达式的语法
lambaa的表达式语法如下:
(int a, int b) -> {return a + b;);
本质上是一个方法。
一般的方法如下:
int add(int a, int b){
return a + b;
}
我们可以看出,一般的方法有返回值,方法名,参数列表,方法体。
而lambda表达式只有参数列表和方法体
(int a, int b) -> {};
():用来描述参数列表
->:称为lambda表达式的运算符,可以叫做箭头符号
{}:用来描述方法体
六种不同参数列表、不同返回类型的lambda表达式
这六种不同参数列表、不同返回类型分别是:
-
无参无返回类型
-
1个参无返回类型
-
2个参无返回类型
-
无参有返回类型
-
1个参有返回类型
-
2个参有返回类型
public class Main {
public static void main(String[] args) {
//无参无返回类型
Cal cal = ()->{
System.out.println("无参无返回类型");
};
cal.test();
//1个参无返回类型
Cal1 cal1 = (int a) -> {
System.out.println("1个参无返回类型");
};
cal1.test(1);
//2个参无返回类型
Cal2 cal2 = (int a, int b) -> {
System.out.println("2个参无返回类型");
};
cal2.test(1, 2);
//无参有返回类型
Cal3 cal3 = ()->{
System.out.println("无参有返回类型");
return 1;
};
System.out.println(cal3.test());
//1个参有返回类型
Cal4 cal4 = (int a) -> {
System.out.println("1个参有返回类型");
return a;
};
System.out.println(cal4.test(1));
//2个参有返回类型
Cal5 cal5 = (int a, int b) -> {
System.out.println("2个参有返回类型");
return a + b;
};
System.out.println(cal5.test(1, 2));
}
}
interface Cal{
//无参无返回类型
void test();
}
interface Cal1{
//1个参无返回类型
void test(int a);
}
interface Cal2{
//2个参无返回类型
void test(int a, int b);
}
interface Cal3{
//无参有返回类型
int test();
}
interface Cal4{
//1个参有返回类型
int test(int a);
}
interface Cal5{
//2个参有返回类型
int test(int a, int b);
}
在使用的时候我们只需要将lambda表达式看成是匿名内部类是用就容易理解了。
lambda表达式的精简
语法注意点:
- 参数类型可以省略
- 假如只有一个参数,()可以省略
- 如果方法体只有一条语句且该语句不是return语句,{}可以省略
- 如果方法体中只有一条语句,且该语句是return语句,省略大括号的同时return也要省略
代码实例如下:
public class Main {
public static void main(String[] args) {
//1个参数无返回类型
Cal1 cal1 = a -> System.out.println("1个参数无返回类型"); //省略(),参数类型,{}
//1个参数有返回类型
Cal2 cal2 = a -> a; //省略(),参数类型,{},return
cal1.test(1);
System.out.println(cal2.test(2));
}
}
interface Cal{
//无参无返回类型
int test(int a, int b);
}
interface Cal1{
//1个参数无返回类型
void test(int a);
}
interface Cal2{
//1个参有返回类型
int test(int a);
}
方法引用
有时候多个lambda表达式实现方式是一样的话,我们可以封装成通用方法便于使用。
如果是非静态方法,格式为 对象名::方法
如果是静态方法。格式为 类名::方法
代码实例如下:
public class Main {
public static void main(String[] args) {
Main m = new Main();
Cal2 cal2 = Main::test1;
System.out.println(cal2.test(1));
}
public static int test1(int a){
return a;
}
}
interface Cal{
//无参无返回类型
int test(int a, int b);
}
interface Cal1{
//1个参数无返回类型
void test(int a);
}
interface Cal2{
//1个参有返回类型
int test(int a);
}
构造方法引用
如果一个函数式接口可以使用一个类的构造方法实现,那么可以使用构造方法引用
格式为
- 类名::new
代码实例:
public class Main {
public static void main(String[] args) {
Service s = Dog::new;
System.out.println(s.getDog());
Service2 s2 = Dog::new;
System.out.println(s2.getDog("小米", 20));
}
}
class Dog{
private String name;
private int age;
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
public Dog() {
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
interface Service{
Dog getDog();
}
interface Service2{
Dog getDog(String name, int age);
}
lambda表达式对于集合的遍历和排序
代码实例如下:
public static void main(String[] args) {
List<Dog> list = new ArrayList<>();
list.add(new Dog("四明", 24));
list.add(new Dog("二明", 22));
list.add(new Dog("三明", 23));
list.add(new Dog("大明", 21));
//lambda对于集合的排序
list.sort((a, b) -> a.getAge() - b.getAge());
//lambda对于集合的遍历
list.forEach(System.out::println);
}
}
class Dog{
private String name;
private int age;
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
public Dog() {
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
函数式接口
如果一个接口有且仅有一个抽象方法,我们称该接口为函数式接口。lambda表达式只能和函数式接口一起使用。
- 如果一个接口只有一个抽象方法,那么该接口就为函数式接口
- java提供@FunctionalInterface注解,如果在某个接口上使用了该注解,那么就会以函数式接口的方式要求该接口,如果不满足函数式接口的要求就会报错。
@FunctionalInterface
interface Cal{
int add();
}