Java基础复习 Day 23
Lambda表达式 & 函数式编程思想
-
函数式编程思想
函数就是有输入量,输出量的一套计算方案。函数式编程思想就是强调做什么,而不是以什么形式去做,避免创建对象或者面向对象这种形式来做。
面向对象的思想:想要做一件事情,就要找能做这件事情的对象,然后通过对象去调用方法
函数式编程思想:只要能获取到结果就可以,谁去做,怎么做不重要,重视结果,不重视过程
-
开启新线程时,当重写Runnable接口的run方法时会有很多冗余的东西
即使使用最简洁的匿名内部类仍然不能避免要重写方法的返回值,方法参数等这些不必要的东西,但是以Runnable为例,实际上重点是在其中重写的run方法体上
public static void main(String[] args) { new Thread(new Runnable(){ @Override public void run() { System.out.println(Thread.currentThread().getName()+" new a thread"); } }).start(); }
-
Lambda表达式
- lambda的引入
是java8的新特性,是Oracle公司在2014年发布1.8之后将怎么做转换成做什么,从而打开了新世界的大门
开启新线程时,重写Runnable的run方法用Lambda方式来实现如下:代码大大简化
//使用lambda表达式来开启一个新线程 new Thread(()->{ System.out.println(Thread.currentThread().getName()+"使用Lambda表达式写法开启线程"); }).start();//Thread-1使用Lambda表达式写法开启线程
-
Lambda表达式的语法:
Lambda由三部分组成:
- 一些参数
- 一个箭头
- 一段代码
Lambda的标准格式为:
(参数类型 参数名称) -> { 代码语句 }
格式的说明:
():中其实就是接口中抽象方法的参数,没有参数就空着,有参数就写出参数,多个参数用逗号分离
->:传递的意思,就是把参数传递给方法使用
{}: 重写方法的方法体
- 有参数的lambda表达式,来实现Comparator接口来通过比较对象年龄来升序降序排列。
//定义一个类 Person package com.kou.lambda.demo2; public class Person { private String name; private int 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; } public Person(String name, int age) { this.name = name; this.age = age; } public Person() { } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } } //测试类中使用匿名内部类和lambda表达式看效果 public static void main(String[] args) { Person[] persons = {new Person("Karen",19),new Person("Kyle",33),new Person("Kate",17),new Person("Kevin",21)}; //匿名内部类实现comparator接口 Arrays.sort(persons, new Comparator<Person>() { @Override public int compare(Person o1, Person o2) { return o1.getAge() - o2.getAge(); } }); for (Person p1 :persons ) { System.out.println(p1); } //通过lambda有参数的形式实现comparator接口 降序看看结果 Arrays.sort(persons, (Person o1, Person o2) -> {return o2.getAge() - o1.getAge();}); for (Person p1 :persons ) { System.out.println(p1); } }
-
有参数有返回值的lambda表达式来实现自定义接口方法
//定义计算接口 public interface Caculator { int caculate(int a, int b); } //测试类用匿名内部类或者是lambda表达式类实现接口 public static void main(String[] args) { //匿名内部类来调用计算接口 invokeCalc(3, 4, new Caculator() { @Override public int caculate(int a, int b) { return a + b; } }); //lambda实现计算接口 invokeCalc(5,6,(int a, int b) -> {return a + b;}); } public static void invokeCalc(int a, int b, Caculator cacul){ int result = cacul.caculate(a,b); System.out.println(result); }
-
Lambda的省略格式
省略的原则:只要可推导,即可省略
具体省略的规则:
-
(参数列表)中的参数的类型可以省略,
-
(参数列表)中的参数如果只有一个,那么类型和()都可以省略。
-
{一些代码}中, 如果只有一行代码,无论有无返回值**{}和return以及;**都可省略。要省略都必须省略,不省略就都别省
//以前的Lambda省略: public static void main(String[] args) { //使用lambda表达式来开启一个新线程 new Thread(()->{ System.out.println(Thread.currentThread().getName()+"使用Lambda表达式写法开启线程"); }).start();//Thread-1使用Lambda表达式写法开启线程 //优化简写Lambda表达式1 new Thread(() -> System.out.println(Thread.currentThread().getName()+"使用Lambda简写形式表达式写法开启线程")).start(); //通过lambda有参数的形式实现comparator接口 降序看看结果 Arrays.sort(persons, (Person o1, Person o2) -> {return o2.getAge() - o1.getAge();}); for (Person p1 :persons ) { System.out.println(p1); } //通过Lambda有参数的简化形式 Arrays.sort(persons,(o1,o2)->o1.getAge()-o2.getAge()); //lambda实现计算接口 invokeCalc(5,6,(int a, int b) -> {return a + b;}); //Lambda的简化形式 invokeCalc(5,8,(a,b) -> a+b); }
-
-
使用Lambda表达式的前提:
-
使用Lambda必须要有接口,且接口中必须有且只有一个抽象方法
不论是JDK内置的Runnable,Comparator接口还是自己定义的接口,要想使用Lambda表达式就必须满足以上条件。
-
使用Lambda表达式必须具有上下文推断,
也就是方法的参数或局部变量类型必须为Lambda对应的接口类型,才能使用Lambda表达式作为该接口的实例。
注意:有且仅有一个方法的接口也叫函数式接口。
-