Lambda
匿名内部类的格式:
new 父类或接口() { 重写的方法; }
在匿名内部类中,有很多内容都是冗余的。
比如在使用匿名内部类实现多线程的代码中。
- 因为 Thread 构造方法中需要传递 Runnable 接口类型的参数,所以我们不得不 new Runnable。
- 因为要重写 Runnable 中的 run 方法,所以不得不写了public void run。
整个匿名内部类中最关键的东西是方法,方法中最关键的有前中后三点。
- 前:参数。
- 中:方法体
- 后:返回值
最好的情况是只关注匿名内部类中最核心的这些内容(方法参数,方法体,返回值)如果使用Lambda表达式,可以只关注最核心的内容,Lambda 表达式是匿名内部类的简化写法。
Lambda 属于函数式编程思想。
- 面向对象思想:怎么做。
- 函数式编程思想:做什么。
public class Demo01Inner { public static void main(String[] args) { //使用匿名内部类的方式实现多线程。 new Thread(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName() + "执行了"); } }).start(); //使用Lambda表达式实现多线程 new Thread(() -> System.out.println(Thread.currentThread().getName() + "执行了")).start(); } }
匿名内部类可以省去单独创建 .java 文件的操作。但是匿名内部类也是有缺点的,写法太冗余了,里面有很多多余的部分。
匿名内部类也有简化写法,匿名内部类的简化写法是 Lambda 表达式匿名内部类中最关键的内容是方法的参数,方法体,以及返回值,而在 Lambda 表达式中,关注的就是这三个关键的东西。
Lambda 表达式的标准格式:
(参数类型 参数名) -> { 方法体; return 返回值; }
格式解释:
- 小括号中的参数和之前方法的参数写法一样,可以写任意个参数,如果多个参数,要使用逗号隔开。
- -> 是一个运算符,表示指向性动作。
- 大括号中的方法体以及 return 返回值的写法和之前方法的大括号中的写法一样。
Lambda 表达式是函数式编程思想。
函数式编程:可推导,就是可省略。
- 因为在 Thread 构造方法中需要 Runnable 类型的参数,所以可以省略 new Runnable。
- 因为 Runnable 中的只有一个抽象方法 run,所以重写的必然是这个 run 方法,所以可以省略 run 方法的声明部分(public void run)
Lambda 表达式可以省略面向对象中的一些条条框框,让我们只关注最核心的内容。
public class Demo02Lambda { public static void main(String[] args) { //实现多线程(单独创建.java) new Thread(new Task()).start(); //使用匿名内部类的方式实现多线程 new Thread(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName() + "执行了"); } }).start(); //使用Lambda表达式完成多线程 new Thread(() -> { System.out.println(Thread.currentThread().getName() + "执行了"); }).start(); } }
匿名内部类与 Lambda 函数比较
public class Demo03Collections { public static void main(String[] args) { //创建集合 List<Student> list = new ArrayList<>(); //添加元素 list.add(new Student("嫐", 20)); list.add(new Student("嬲", 18)); list.add(new Student("挊", 22)); //使用比较器排序对集合中的学生对象根据年龄升序排序 //Collections.sort(list, new Rule()); //使用匿名内部类 Collections.sort(list, new Comparator<Student>() { @Override public int compare(Student o1, Student o2) { return o1.getAge() - o2.getAge(); } }); //使用Lambda表达式 Collections.sort(list, (Student o1, Student o2) -> { return o1.getAge() - o2.getAge(); }); Collections.sort(list, (o1, o2) -> o1.getAge() - o2.getAge()); System.out.println(list); } }
Lambda 格式
Lambda 表达式的标准格式:
(参数类型 参数名) -> { 方法体; return 返回值; }
Lambda 表达式的省略规则:
- 1. 小括号中的参数类型可以省略。
- 2. 如果小括号中只有一个参数,那么可以省略小括号。
- 3. 如果大括号中只有一条语句,那么可以省略大括号,return,分号。
public class Demo04SimpleLambda { //定义方法,使用接口当做参数 public static void method(MyInterface m) { m.printStr("hello"); } public static void main(String[] args) { //调用method方法,参数传递MyInterface实现类对象 method(new MyInterface() { @Override public void printStr(String str) { System.out.println(str); } }); //使用Lambda表达式的标准格式。 method((String str) -> { System.out.println(str); }); //1. 小括号中的参数类型可以省略。 method((str) -> { System.out.println(str); }); //2. 如果小括号中只有一个参数,那么可以省略小括号。 method(str -> { System.out.println(str); }); //3. 如果大括号中只有一条语句,那么可以省略大括号,return,分号。 method(str -> System.out.println(str)); } }
Lambda 使用条件
Lambda 表达式的使用前提:
- 必须有接口(不能是抽象类),接口中有且仅有一个需要被重写的抽象方法。
- 必须支持上下文推导,要能够推导出来 Lambda 表达式表示的是哪个接口中的内容。
可以使用接口当做参数,然后传递 Lambda 表达式(常用),也可以将 Lambda 表达式赋值给一个接口类型的变量。
public class Demo05BeforeLambda { //使用接口当做参数 public static void method(MyInterface m) {//m = s -> System.out.println(s) m.printStr("HELLO"); } public static void main(String[] args) { //使用接口当做参数,然后传递Lambda表达式。 //method(s -> System.out.println(s)); //使用匿名内部类方式创建对象 /* MyInterface m = new MyInterface() { @Override public void printStr(String str) { System.out.println(str); } }; */ MyInterface m = str -> System.out.println(str); m.printStr("Hello"); } }
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.bianchenghao6.com/java-jiao-cheng/14501.html