目录
Lambda 表达式
方法引用
静态方法的引用
实例方法的引用
特定类型的方法引用
构造器引用
● Lambda 表达式是 JDK 8开始新增的一种语法形式;
作用:用于简化匿名内部类的代码写法。
格式
(被重写方法的形参列表)->{
被重写方法的方法体代码。}
注意: Lambda 表达式只能简化函数式接口的匿名内部类!!!
什么是函数式接口?
.有且仅有一个抽象方法的接口。
●注意:将来我们见到的大部分函数式接口,上面都可能会有一个@ Functionalinterface 的注解,有该注解的接口就必定是函数式接口。
Test1
package com.xinbao.d6_lambda;
public class LambdaTest1 {
public static void main(String[] args) {
Animal a = new Animal() {
@Override
public void run() {
System.out.println("匿名内部类");
}
};
a.run();
//报错:Lambda表达式不能简化全部匿名内部类,只能简化函数式接口(有且仅有一个抽象方法的接口)的匿名内部类
// Animal a = () -> {
// System.out.println("匿名内部类");
// };
Swimming s = new Swimming() {
@Override
public void swim() {
System.out.println("swim");
}
};
s.swim();
Swimming s2 = () -> {
System.out.println("swimswim");
};
s2.swim();
}
}
abstract class Animal{
public abstract void run();
}
interface Swimming{
void swim();
}
Test2
package com.xinbao.d6_lambda;
import com.xinbao.d5_arrays.Student;
import java.util.Arrays;
import java.util.Comparator;
import java.util.function.IntToDoubleFunction;
public class LambdaTest2 {
public static void main(String[] args) {
//目标:使用Lambda简化函数式接口
double[] prices = {11,33,55,66.9};
// Arrays.setAll(prices, new IntToDoubleFunction() {
// @Override
// public double applyAsDouble(int value) {
// return prices[value] * 0.8;
// }
// });
Arrays.setAll(prices,(int value) -> {
return prices[value] * 0.8;
});
System.out.println(Arrays.toString(prices));
System.out.println("------------------------");
Student[] students = new Student[4];
students[0] = new Student("Bob",182.9,22);
students[1] = new Student("Tom",186.9,21);
students[2] = new Student("David",185.9,18);
students[3] = new Student("Cherry",165.9,20);
// Arrays.sort(students, new Comparator() {
// @Override
// public int compare(Student o1, Student o2) {
// return Double.compare(o1.getHeight(),o2.getHeight());
// }
// });
Arrays.sort(students, (Student o1, Student o2) -> {
return Double.compare(o1.getHeight(),o2.getHeight());
});
System.out.println(Arrays.toString(students));
}
}
E:\JVsoft\Java\jdk-17\bin\java.exe -javaagent:E:\JVsoft\IntelliJIDEA2021.1.1\lib\idea_rt.jar=56607:E:\JVsoft\IntelliJIDEA2021.1.1\bin -Dfile.encoding=UTF-8 -classpath E:\JVsoft\code\out\production\api-app2 com.xinbao.d6_lambda.LambdaTest2
[8.8, 26.400000000000002, 44.0, 53.52000000000001]
------------------------
[Student{name='Cherry', height=165.9, age=20}, Student{name='Bob', height=182.9, age=22}, Student{name='David', height=185.9, age=18}, Student{name='Tom', height=186.9, age=21}]
Process finished with exit code 0
Lambda 表达式的省略写法(进一步简化 Lambda 表达式的写法)
·参数类型可以省略不写。
●如果只有一个参数,参数类型可以省略,同时()也可以省略。
●如果 Lambd 表达式中的方法体代码只有一行代码,可以省略大括号不写,同时要省略分号!此时,如
果这行代码是 return 语句,也必须去掉 return 不写。
package com.xinbao.d6_lambda;
import com.xinbao.d5_arrays.Student;
import java.util.Arrays;
import java.util.Comparator;
import java.util.function.IntToDoubleFunction;
public class LambdaTest2 {
public static void main(String[] args) {
//目标:使用Lambda简化函数式接口
double[] prices = {11,33,55,66.9};
// Arrays.setAll(prices, new IntToDoubleFunction() {
// @Override
// public double applyAsDouble(int value) {
// return prices[value] * 0.8;
// }
// });
// Arrays.setAll(prices,(int value) -> {
// return prices[value] * 0.8;
// });
// Arrays.setAll(prices,value -> {
// return prices[value] * 0.8;
// });
Arrays.setAll(prices,value -> prices[value] * 0.8);
System.out.println(Arrays.toString(prices));
System.out.println("------------------------");
Student[] students = new Student[4];
students[0] = new Student("Bob",182.9,22);
students[1] = new Student("Tom",186.9,21);
students[2] = new Student("David",185.9,18);
students[3] = new Student("Cherry",165.9,20);
// Arrays.sort(students, new Comparator() {
// @Override
// public int compare(Student o1, Student o2) {
// return Double.compare(o1.getHeight(),o2.getHeight());
// }
// });
// Arrays.sort(students, (Student o1, Student o2) -> {
// return Double.compare(o1.getHeight(),o2.getHeight());
// });
// Arrays.sort(students, (o1, o2) -> {
// return Double.compare(o1.getHeight(),o2.getHeight());
// });
Arrays.sort(students, (o1, o2) -> Double.compare(o1.getHeight(),o2.getHeight()));
System.out.println(Arrays.toString(students));
}
}
类名::静态方法。
使用场景
.如果某个 Lambda 表达式里只是调用一个静态方法,并且前后参数的形式一致,就可以使用静态方法引用。
对象名::实例方法。
使用场景
●如果某个 Lambda 表达式里只是调用一个实例方法,并且前后参数的形式一致,就可以使用实例方法引用。
package com.xinbao.d6_lambda;
import com.xinbao.d5_arrays.Student;
public class CompareByData {
public static int compareByAge(Student o1, Student o2){
return o1.getAge() - o2.getAge();
}
public int compareByAgeDesc(Student o1,Student o2){
return o2.getAge() - o1.getAge();//降序
}
}
package com.xinbao.d6_lambda;
import com.xinbao.d5_arrays.Student;
import java.util.Arrays;
import java.util.Comparator;
public class Test3 {
public static void main(String[] args) {
Student[] students = new Student[4];
students[0] = new Student("Bob",182.9,22);
students[1] = new Student("Tom",186.9,21);
students[2] = new Student("David",185.9,18);
students[3] = new Student("Cherry",165.9,20);
// Arrays.sort(students, new Comparator() {
// @Override
// public int compare(Student o1, Student o2) {
// return o1.getAge() - o2.getAge();
// }
// });
//使用Lambda化简后的形式
// Arrays.sort(students,(o1, o2) -> o1.getAge() - o2.getAge());
//将return封装到静态方法中
// Arrays.sort(students,(o1, o2) -> CompareByData.compareByAge(o1, o2));
//静态方法引用
Arrays.sort(students,CompareByData::compareByAge);
CompareByData compare = new CompareByData();
// Arrays.sort(students,((o1, o2) -> compare.compareByAgeDesc(o1, o2)));
//实例方法引用
Arrays.sort(students,(compare::compareByAgeDesc));
}
}
E:\JVsoft\Java\jdk-17\bin\java.exe -javaagent:E:\JVsoft\IntelliJIDEA2021.1.1\lib\idea_rt.jar=58601:E:\JVsoft\IntelliJIDEA2021.1.1\bin -Dfile.encoding=UTF-8 -classpath E:\JVsoft\code\out\production\api-app2 com.xinbao.d6_lambda.Test3
[Student{name='David', height=185.9, age=18}, Student{name='Cherry', height=165.9, age=20}, Student{name='Tom', height=186.9, age=21}, Student{name='Bob', height=182.9, age=22}]
[Student{name='Bob', height=182.9, age=22}, Student{name='Tom', height=186.9, age=21}, Student{name='Cherry', height=165.9, age=20}, Student{name='David', height=185.9, age=18}]
Process finished with exit code 0
类型::方法。
使用场景
●如果某个 Lambda 表达式里只是调用一个实例方法,并且前面参数列表中的第一个参数是作为方法的主调,后面的所有参数都是作为该实例方法的入参的,则此时就可以使用特定类型的方法引用。
package com.xinbao.d6_lambda;
import java.util.Arrays;
import java.util.Comparator;
public class Test4 {
public static void main(String[] args) {
String[] names = {"baby","angela","Andy","dlei","cindy","Babo","jaCk","CIci"};
Arrays.sort(names);
System.out.println(Arrays.toString(names));//[Andy, Babo, CIci, angela, baby, cindy, dlei, jaCk]
//忽略首字母大小进行排序
// Arrays.sort(names, new Comparator() {
// @Override
// public int compare(String o1, String o2) {
// return o1.compareToIgnoreCase(o2);
// }
// });
//Lambda表达式
// Arrays.sort(names,(o1,o2) -> o1.compareToIgnoreCase(o2));
//特定类型的方法引用
Arrays.sort(names,String::compareToIgnoreCase);
System.out.println(Arrays.toString(names));//[Andy, angela, Babo, baby, CIci, cindy, dlei, jaCk]
}
}
类名:: new 。
使用场景
.如果某个 Lambda 表达式里只是在创建对象,并且前后参数情况一致,就可以使用构造器引用。
package com.xinbao.d6_lambda;
public class Car {
private String name;
private double price;
@Override
public String toString() {
return "Car{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
public Car(String name, double price) {
this.name = name;
this.price = price;
}
public Car() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
package com.xinbao.d6_lambda;
public class Test5 {
public static void main(String[] args) {
//1、创建这个接口的匿名内部类对象
// CreaterCar car = new CreaterCar() {
// @Override
// public Car create(String name, double price) {
// return new Car("特斯拉",100.5);
// }
// };
//Lambda表达式
//CreaterCar car = (name, price) -> new Car("特斯拉",100.5);
//构造器引用
CreaterCar car = Car::new;
Car c = car.create("特斯拉",100.5);
System.out.println(c);//Car{name='特斯拉', price=100.5}
}
}
interface CreaterCar{
Car create(String name,double price);//抽象类
}