1.lambda表达式
1.定义
- lambda表达式是jdk8的一个新特性,可以取代大部分的匿名函数,写出更优雅的java代码,尤其在集合遍历和其他集合操作中,可以极大的优化代码结构
- jdk1.8(java8)也提供了大量的内置函数式接口供我们使用,使用Lambda表达式的运用更加方便、高效
- Lambda表达式一定要配合函数式接口一起使用!
- 所谓函数式接口,就是接口中只有一个抽象方法的接口就是函数式接口,jdk也内置了函数式接口。
2.函数式接口
-
接口中只有一个抽象方法的接口就是函数式接口。
-
可以通过@FunctionInterface注解来标注该接口是一个函数式接口。
-
函数式接口只有一种情况不只有一个抽象方法,那么就是可以继承Object类的方法
-
函数式接口用法
@FunctionInterface public interface Test2{ void show(); //@FunctionInterface注解来标注该接口是一个函数式接口,这个类只有一个抽象方法 // void show2(); }
-
jdk内置的函数式接口
@FunctionInterface public interface Runnable{ public abstract void run(); }
-
有一种情况函数式接口有多个方法,那就继承了Object类里面的方法,比如:
@FunctionInterface public interface Test2{ void show(); //@FunctionInterface注解来标注该接口是一个函数式接口,这个类只有一个抽象方法 @Override void toString(); }
3.定义一个Lambda表达式
无参Lambda表达式
-
Student接口
@FunctionalInterface public interface Student { void eat(); }
-
测试
public class MyStudentTest { public static void main(String[] args) { //匿名内部类写法,写了一个匿名内部类重写类eat方法做具体实现 Student test2 = new Student() { @Override public void eat() { System.out.println("我是学生,我吃牛排"); } }; //Lambda表达式写法 //Lambda表达式语法: /** * 参数列表: * 参数1:():Student接口中能个唯一抽象方法eat方法的参数 * 参数2:-> * 参数3:{具体实现}:Student接口中能个唯一抽象方法eat方法的重写做具体实现 */ Student test = ()->{ System.out.println("学生吃米粉!"); }; test.eat(); } }
有参Lambda表达式
-
Student接口
@FunctionalInterface public interface Student { void eat(String a); }
-
测试
public class MyStudentTest { public static void main(String[] args) { //Lambda表达式写法 //Lambda表达式语法: /** * 参数列表: * 参数1:():Student接口中能个唯一抽象方法eat方法的参数 * 参数2:-> * 参数3:{具体实现}:Student接口中能个唯一抽象方法eat方法的重写做具体实现 */ Student test = (a)->{ System.out.println("学生吃"+a); }; test.eat("米粉"); } }
4.Lambda表达式实现多线程
-
匿名内部类写法
public class Test02 { public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { System.out.println("hello,world!"); } }).start(); } }
-
Lambda表达式写法
public class Test01 { public static void main(String[] args) { new Thread(()->{ System.out.println("hello,world!"); }).start(); } }
5.Lambda表达式操作1:
-
接口
public interface Calculator<T> { T operztion(T t1,T t2); }
-
测试
public class Test { /** * 计算方法 * @param v1 * @param v2 * @param calculator 以父类接口Calculator为参数实现多态调用operation方法 * @return v1和v2的算术结果值 */ public Integer operator(Integer v1,Integer v2,Calculator<Integer> calculator) { return calculator.operztion(v1, v2); } public Integer add(Integer v1,Integer v2) { // return this.operator(v1, v2, (a,b)->{ // return a+b; // }); //可以简化如下: return this.operator(v1, v2, (a,b)->a+b); } public Integer substr(Integer v1,Integer v2) { return this.operator(v1, v2, (a,b)->a-b); } public Integer mulyi(Integer v1,Integer v2) { return this.operator(v1, v2, (a,b)->a*b); } public static void main(String[] args) { Test test = new Test(); int num = test.add(12, 24); System.out.println("结果1=>" + num); int sub = test.substr(12, 24); System.out.println("结果2=>" + sub); int mul = test.mulyi(12, 24); System.out.println("结果3=>" + mul); } }
6.Lambda表达式操作2:
-
无返回值无参数接口
/** * 无返回值无参数的方法 * @author Administrator * */ @FunctionalInterface public interface NoReturnNOParam { void method(); }
-
无返回值一个参数接口
/** * 无返回值一个参数的方法 * @author Administrator * */ @FunctionalInterface public interface NoReturnOneParam { void method(int a); }
-
无返回值多个参数接口
/** * 无返回多参数方法 * @author Administrator * */ @FunctionalInterface public interface NoReturnMultiParam { void method(int a,int b); }
-
有返回值无参数接口
/** * 有返回值无参方法 * @author Administrator * */ @FunctionalInterface public interface ReturnNoParam { int method(); }
-
有返回值一个参数接口
/** * 有返回值一个参数方法 * @author Administrator * */ @FunctionalInterface public interface ReturnOneParam { int method(int a); }
-
有返回值多个参数接口
/** * 有返回值多个参数的方法 * @author Administrator * */ @FunctionalInterface public interface ReturnMutilParam { int method(int a,int b); }
-
测试
import day05.inter.NoReturnMultiParam; import day05.inter.NoReturnNOParam; import day05.inter.NoReturnOneParam; import day05.inter.ReturnMutilParam; import day05.inter.ReturnNoParam; import day05.inter.ReturnOneParam; public class Test { public static void main(String[] args) { //无返回值无参方法 NoReturnNOParam noReturnNOParam = ()->{ System.out.println("对无返回值无参方法做具体实现!"); }; noReturnNOParam.method(); //简化版1:当具体实现的方法里面只有一条语句,就可以简化{}; NoReturnNOParam lambda1 = ()->System.out.println("对无返回值无参方法做具体实现!"); lambda1.method(); /******************************************************/ //无返回值一个参数 NoReturnOneParam noReturnOneParam =(a)->{ System.out.println("对无返回值一个参数方法做具体实现=>"+a); }; noReturnOneParam.method(11); //简化版1: NoReturnOneParam lambda2 = (a)->System.out.println("对无返回值一个参数方法做具体实现=>"+a); lambda2.method(10); //简化版2:如果参数只有一个,可以省略() NoReturnOneParam lambda3 =a->System.out.println("对无返回值一个参数方法做具体实现=>"+a); lambda3.method(12); /***********************************************************************/ //无返回值多个参数 NoReturnMultiParam noReturnMultiParam =(int a,int b)->{ System.out.println("对无返回值多个参数的方法做具体实现;参数a=>"+a+",参数b=>"+b); }; noReturnMultiParam.method(5, 6); //简化版1: NoReturnMultiParam lambda5 =(a,b)->{ System.out.println("对无返回值多个参数的方法做具体实现;参数a=>"+a+",参数b=>"+b); }; lambda5.method(5, 6); //简化版2: NoReturnMultiParam lambda6 =(a,b)->System.out.println("对无返回值多个参数的方法做具体实现;参数a=>"+a+",参数b=>"+b); lambda6.method(5, 6); /*************************************************************************/ //有返回值无参方法 ReturnNoParam returnNoParam = ()->{ System.out.println("对有返回值无参方法的实现"); return 1; }; int result1 = returnNoParam.method(); System.out.println("返回值1:"+result1); //简化版 ReturnNoParam returnNoParam1 = ()->10; int result2 = returnNoParam1.method(); System.out.println("返回值2:"+result2); /***************************************************************/ //有返回值一个参数方法 ReturnOneParam returnOneParam = (int a)->{ System.out.println("对有返回值一个参数的具体实现:"+a); return 100; }; int result3 = returnOneParam.method(5); System.out.println("返回值3:"+result3); //简化版 ReturnOneParam lambda7=a->{ System.out.println("对有返回值一个参数的具体实现:"+a); return 100; }; int result4 = lambda7.method(5); System.out.println("返回值4:"+result4); //简化版2 ReturnOneParam lambda8=a->a+100; int result5 = lambda8.method(5); System.out.println("返回值5:"+result5); /**************************************************/ //有返回值多个参数方法 ReturnMutilParam returnMutilParam = (a,b)->{ System.out.println("对有返回值多个参数的方法的具体实现"); return a+b; }; int result6 = returnMutilParam.method(45, 20); System.out.println("返回值6:"+result6); //简化版 ReturnMutilParam lambda9 = (a,b)->a*b; int result7 = lambda9.method(45, 20); System.out.println("返回值7:"+result7); } }
2.方法引用
1.方法引用定义
- 有时候我们不是必须要重写匿名内部类对接口的方法做具体实现,我们也可以通过方法引用来引用已经存在的方法接口中的方法做具体实现。
2.引用静态方法和非静态方法
-
接口
@FunctionalInterface public interface ReturnOneParam { int method(int a); }
-
测试
public class Test { public int addTo(int a) { return a*10; } public static int doubleNum(int a) { return a+100; } public static void main(String[] args) { // ReturnOneParam lambda1 = (a)->a+10; // int result1 = lambda1.method(8); // System.out.println("结果1=>"+result1); /** * 方法引用的作用: * 有时候我们不是必须要重写匿名内部类对接口的方法做具体实现,我们也可以通过方法引用来引用已经存在的方法接口中的方法做具体实现 */ Test test = new Test(); //调用非静态方法 //调用已经存在的方法对接口中定义的method方法做具体实现 //(a)->a+10;是对method接口的方法定义了一个实现匿名类,重写了method方法 //test::addTo;表示的是定义了一个匿名实现类重写了method方法,这个实现的method方法里面调用了已经存在的addTo方法 ReturnOneParam lambda2 = test::addTo; int result2 = lambda2.method(10); System.out.println("结果2=>"+result2); ReturnOneParam lambda3 = Test::doubleNum; int result3 = lambda3.method(5); System.out.println("结果3=>"+result3); ReturnOneParam lambda4 = a->doubleNum(a); int result4 = lambda4.method(5); System.out.println("结果4=>"+result4); } }
3.引用构造方法方法
-
student类
public class Student { private String name; private int age; public Student() { super(); } public Student(String name, int age) { super(); this.name = name; this.age = age; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } }
-
接口
public interface StudentCreate { //Student getStudent(); Student getStudent(String name,int age); }
-
测试
public class Test { public static void main(String[] args) { //调用无参构造方法创建对象 // StudentCreate student1 = ()->{return new Student();}; //简化版1: // StudentCreate student2 = ()->new Student(); // System.out.println(student2); //构造方法引用 // StudentCreate student3 = Student::new; // System.out.println(student3.getStudent()); //Student::new是调用StudentCreate接口定义的唯一构造方法 StudentCreate student4 = Student::new; System.out.println(student4.getStudent("张三",18)); StudentCreate student5 = Student::new; Student student = student5.getStudent("李四",18); System.out.println(student.toString()); } }
3.Lambda表达式操作集合
-
遍历集合
import java.util.ArrayList; import java.util.Collections; public class Test1 { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<Integer>(); //给集合按序添加元素 Collections.addAll(list, 1,2,3,4,5,6,7); //通过forEach方法里面的参数consumer接口就是一个函数式接口,我们对该函数通过Lambda表达式做具体实现 //遍历获取到了集合的数据 // list.forEach(element->{System.out.println(element);}); //这句同上作用一致,通过System.out对象引用已存在的println方法做具体实现 // list.forEach(System.out::println); //还等同于 // for (Integer i : list) { // System.out.println(i); // } //遍历元素,取到偶数 list.forEach(element->{ if(element%2==0) { System.out.println(element); } }); } }
-
集合删除
Student类
public class Student { private Integer id; private String name; public Student() { super(); } public Student(Integer id, String name) { super(); this.id = id; this.name = name; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Student [id=" + id + ", name=" + name + "]"; } }
测试
import java.util.ArrayList; import java.util.List; public class Test { public static void main(String[] args) { List<Student> list = new ArrayList<Student>(); list.add(new Student(11,"张三")); list.add(new Student(12,"李四")); list.add(new Student(13,"王五")); list.add(new Student(14,"赵六")); //删除id=12的Student对象 // list.removeIf(ele->ele.getId()==12); // list.forEach(System.out::println); } }
-
集合排序
//定制排序 list.sort((o1,o2)->o2.getId()-o1.getId()); list.forEach(System.out::println);