java 8引入的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表达式。
lambaa的表达式语法如下:
(int a, int b) -> {return a + b;);
本质上是一个方法。
一般的方法如下:
int add(int a, int b){ return a + b; }
我们可以看出,一般的方法有返回值,方法名,参数列表,方法体。
而lambda表达式只有参数列表和方法体
(int a, int b) -> {};
():用来描述参数列表
->:称为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表达式看成是匿名内部类是用就容易理解了。
语法注意点:
代码实例如下:
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); }
如果一个函数式接口可以使用一个类的构造方法实现,那么可以使用构造方法引用
格式为
代码实例:
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); }
代码实例如下:
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表达式只能和函数式接口一起使用。
@FunctionalInterface interface Cal{ int add(); }