Lambda表达式
lambda是一种匿名函数:
正常的函数 :
返回值 方法名 (参数列表){
方法体;
}
lambda表达式
(参数列表)->方法体;
函数式接口
要了解Lambda表达式,首先需要了解什么是函数式接口;函数式接口定义:一个接口有且只有一个抽象方法.
1.如果一个接口只有一个抽象方法,那么该接口就是一个函数是接口 2.如果我们在某个接口上声明@FunctionalInterface 注解,那么编译器就会按照函数式接口的定义来要求该接口,这样如果有两个抽象方法,程序编译就会报错的。所以,从某种意义来说,只要你保证你的接口中只有一个抽象方法,你可以不加这个注解。加上就会自动进行检测的。
@FunctionalInterface interface NoParameterNoReturn{ void test(); // void test1(); // void test2();//只能有一个方法,当有多个方法就会报错 }
lambda表达式的基本使用
使代码变简洁,但是可读性变差。
无参数无返回值
@FunctionalInterface interface NoParameterNoReturn{ void test(); } public static void main(String[] args) { NoParameterNoReturn noParameterNoReturn = new NoParameterNoReturn() { @Override public void test() { System.out.println("哈哈"); } }; noParameterNoReturn.test(); System.out.println("================================="); //使用lambda表达式 NoParameterNoReturn noParameterNoReturn1 = ()-> System.out.println("haha"); noParameterNoReturn1.test(); }
运行结果:
一个参数无返回值
//无返回值一个参数 @FunctionalInterface interface OneParameterNoReturn { void test(int a); } public static void main(String[] args) { //OneParameterNoReturn oneParameterNoReturn = (int a) -> System.out.println(a); OneParameterNoReturn oneParameterNoReturn = a -> System.out.println(a); oneParameterNoReturn.test(10); }
运行结果:
多个参数无返回值
//无返回值多个参数 @FunctionalInterface interface MoreParameterNoReturn { void test(int a,int b); } public static void main(String[] args) { MoreParameterNoReturn moreParameterNoReturn = (int a,int b)-> System.out.println(a+b); // MoreParameterNoReturn moreParameterNoReturn = // (a,b)-> System.out.println(a+b);//类型可以省略,但是一般不建议省略类型 moreParameterNoReturn.test(10,20); }
运行结果:
无参数有返回值
//有返回值无参数 @FunctionalInterface interface NoParameterReturn { int test(); } public static void main(String[] args) { // NoParameterReturn noParameterReturn = ()-> {return 10;}; NoParameterReturn noParameterReturn = ()-> 10; System.out.println(noParameterReturn.test()); }
运行结果:
一个参数有返回值
//有返回值一个参数 @FunctionalInterface interface OneParameterReturn { int test(int a); } public static void main(String[] args) { // OneParameterReturn oneParameterReturn = (int a)-> a; OneParameterReturn oneParameterReturn = a-> a; System.out.println(oneParameterReturn.test(19)); }
运行结果:
多个参数有返回值
@FunctionalInterface interface MoreParameterReturn { int test(int a,int b); } public static void main(String[] args) { // MoreParameterReturn moreParameterReturn = (int a,int b) -> a + b; MoreParameterReturn moreParameterReturn = (a,b) -> a + b; System.out.println(moreParameterReturn.test(10, 20)); }
运行结果:
变量捕获
匿名内部类的变量捕获
class Test{ public void func(){ System.out.println("func()"); } public static void main(String[] args) { int a = 10; new Test(){ @Override public void func(){ //a = 99;若改变a的值就会报错 System.out.println("这是一个重写的内部类方法"); System.out.println("我是一个常量或者是一个没有改变过值的变量" + a);//这里a就是一个被捕获的变量 } }.func(); }
上述代码中a就是被捕获的变量,这个变量要么是个常量(被final修饰),要么就是没有被改变的量,若a的值被修稿就会编译报错。
lambda中的变量捕获
在lambda表达式中也可以进行变量捕获,效果与匿名内部类一样。
@FunctionalInterface interface NoParameterNoReturn{ void test(); } public static void main(String[] args) { int a = 10; //使用lambda表达式 NoParameterNoReturn noParameterNoReturn1 = ()->{ //a = 99;编译报错 System.out.println("捕获变量:" + a); }; noParameterNoReturn1.test(); }
Lambda在集合中的使用
foreach方法
public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("Hello"); list.add("world"); list.add("hello"); list.add("lambda"); list.forEach(new Consumer<String>() { @Override public void accept(String s) { System.out.println(s); } }); System.out.println("==========================="); list.forEach(s -> System.out.println(s)); }
运行结果:
sort方法
public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("Hello"); list.add("world"); list.add("hello"); list.add("lambda"); System.out.println(list); // list.sort(new Comparator<String>() { // @Override // public int compare(String o1, String o2) { // return o1.compareTo(o2); // } // }); // System.out.println(list); System.out.println("==========================="); list.sort((o1,o2) -> { return o1.compareTo(o2); }); System.out.println(list); }
运行结果:
优点:
1.代码简洁;
2.方便函数式编程
3.非常容易进行并行操作(?)
4.改善了集合的操作
缺点;
1.代码可读性变差
2.在非并行计算中,很多计算未必有传统的for性能要高
3.不容易进行调试