最近JDK13都出来了,所以想沉下心来,总结一下JDK的一系列新语法。这个模块将抽空慢慢填充完整。
这一章就先写下Lambda表达式吧。下面我会以代码的形式进行表达
一、Lambda表达式语法
/**
* 一、函数式接口:即接口类中只有一个方法,如compareInterface
* 二、lambda表达式的基础语法:引入了一个新的操作符 "->"
* 箭头左侧: 参数列表--即函数式接口方法中的参数列表
* 箭头右侧: 执行方法--即函数式接口方法中的实现方法
*
* 三、语法格式:
* 1、 无参函数--无返回值
* ()->System.out.println("Hello Lambda");
* 2、 一个参数--无返回值
* (e)->System.out.println("hello Lambda2");
* 或
* e->System.out.println("hello Lambda2");
* 3、 两个参数--一个返回值,一条语句
* (e1,e2)-> return e1-e2;
* 或
* (e1,e2)-> e1-e2; //return 和 {} 都可以省略不写
*
* 两个参数--一个返回值,多条语句
* (e1,e2)->{
* System.out.println("hello Lambda");
* return e1-e2;
* }
*
* 注意:lambda表达式的参数列表可以 不写 参数类型,JVM会根据上下文进行推断
*
*/
1、先来认识一下Lambda
package com.lee.jdk.lambda;
import org.junit.Test;
import java.util.Arrays;
import java.util.Comparator;
public class TestLamda {
//原来的匿名内部类
@Test
public void test01(){
Integer[] arr = {2,7,1,5,3};
Arrays.sort(arr, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1,o2);
}
});
for (int i=0;i<arr.length;i++){
System.out.print(arr[i]+" ");
}
}
//lambda
@Test
public void test02(){
Integer[] arr = {2,7,1,5,3};
Arrays.sort(arr,(o1,o2)->Integer.compare(o1,o2));
for (int i=0;i<arr.length;i++){
System.out.print(arr[i]+" ");
}
}
}
2、Lambda的语法规则和认知
Employee实体,下面会用到
package com.lee.jdk.Entity;
public class Employee {
private Integer id;
private String name;
private int age;
private Double salary;
public Employee() {
}
public Employee(Integer id) {
this.id = id;
}
public Employee(Integer id, String name) {
this.id = id;
this.name = name;
}
public Employee(Integer id, String name, int age, Double salary) {
this.id = id;
this.name = name;
this.age = age;
this.salary = salary;
}
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;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", salary=" + salary +
'}';
}
}
CompareInterface接口下面也会用到
package com.lee.jdk.Entity;
public interface CompareInterface<T> {
Boolean myCompare(T t);
}
CompareImpl接口实现
package com.lee.jdk.Entity;
public class CompareImpl implements CompareInterface<Employee> {
@Override
public Boolean myCompare(Employee employee) {
return employee.getAge()>35;
}
}
Lambda的语法规则:
package com.lee.jdk.lambda;
import com.lee.jdk.Entity.CompareImpl;
import com.lee.jdk.Entity.CompareInterface;
import com.lee.jdk.Entity.Employee;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.function.Consumer;
/**
* 一、函数式接口:即接口类中只有一个方法,如compareInterface
* 二、lambda表达式的基础语法:引入了一个新的操作符 "->"
* 箭头左侧: 参数列表--即函数式接口方法中的参数列表
* 箭头右侧: 执行方法--即函数式接口方法中的实现方法
*
* 三、语法格式:
* 1、 无参函数--无返回值
* ()->System.out.println("Hello Lambda");
* 2、 一个参数--无返回值
* (e)->System.out.println("hello Lambda2");
* 或
* e->System.out.println("hello Lambda2");
* 3、 两个参数--一个返回值,一条语句
* (e1,e2)-> return e1-e2;
* 或
* (e1,e2)-> e1-e2; //return 和 {} 都可以省略不写
*
* 两个参数--一个返回值,多条语句
* (e1,e2)->{
* System.out.println("hello Lambda");
* return e1-e2;
* }
*
* 注意:lambda表达式的参数列表可以 不写 参数类型,JVM会根据上下文进行推断
*
*/
public class TestLambda2 {
List<Employee> employeeList = Arrays.asList(
new Employee(1,"张三",25,17000d),
new Employee(2,"李四",18,19000d),
new Employee(3,"王五",55,7000d),
new Employee(4,"赵六",39,12000d),
new Employee(5,"刘七",28,14000d)
);
public List<Employee> filterEmployee(List<Employee> employeeList, CompareInterface<Employee> ci){
List<Employee> resList = new ArrayList<>();
for (Employee emp: employeeList) {
if(ci.myCompare(emp)){
resList.add(emp);
}
}
return resList;
}
//1、匿名内部类
@Test
public void test1(){
//年龄>35
List<Employee> employees = filterEmployee(employeeList, new CompareImpl());
for (Employee emp: employees) {
System.out.println(emp);
}
System.out.println("------------------------");
List<Employee> employees2 = filterEmployee(employeeList, new CompareInterface<Employee>() {
@Override
public Boolean myCompare(Employee employee) {
return employee.getAge()>35;
}
});
for (Employee emp: employees2) {
System.out.println(emp);
}
}
//2、lambda表达式简写匿名内部类
@Test
public void test2(){
//年龄>35
List<Employee> employees = filterEmployee(employeeList,(e)-> e.getAge()>35);
for (Employee emp: employees) {
System.out.println(emp);
}
}
//3、语法格式一:()-> 无返回值
@Test
public void test3(){
Runnable r1 = new Runnable() {
@Override
public void run() {
System.out.println("hello world");
}
};
r1.run();
System.out.println("-------------");
Runnable r2 = ()-> System.out.println("hello lambda");
r2.run();
}
//4、语法格式二:(e)-> 无返回值
@Test
public void test4(){
Consumer<String> consumer = new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println("hello world--->"+s);
}
};
consumer.accept("你好世界!");
System.out.println("------------------------------");
Consumer consumer1 = (e)-> System.out.println("hello Lambda--->"+e);
consumer1.accept("你好Lambda!");
}
//5、语法格式三:(e1,e2)->一个返回值,一条或多条语句
@Test
public void test5(){
Comparator<Integer> comp = (x,y)->x-y;
System.out.println(comp.compare(12, 3));
System.out.println("===================");
Comparator<Integer> comp1 = (x,y)->{
System.out.println("hello lambda");
return x-y;
};
System.out.println(comp1.compare(12, 3));
}
}
3、JDK8内置的4大核心函数,以及其Lambda的表达
package com.lee.jdk.lambda;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
* JAVA8 内置4大核心函数式接口
*
* 1、Consumer<T> 消费性接口
* void accept(T t)
*
* 2、Supplier<T> 供给型接口
* T get()
*
* 3、Function<T,R> 函数型接口
* R apply(T t)
*
* 4、Predicate<T> 断言型接口: 判断操作
* boolean tesst<T t>
*/
public class TestLambda3 {
//1、消费式接口:Consumer<T>
@Test
public void test1(){
happy(10000,(m)-> System.out.println("刚哥喜欢大宝剑,每次消费"+m+"元"));
}
public void happy(double money, Consumer<Double> con){
con.accept(money);
}
//2、供给型接口:Supplier<T>
@Test
public void test2(){
List<Integer> numberList = getNumberList(10, () -> (int) (Math.random() * 100));
for (Integer i : numberList) {
System.out.println(i);
}
}
public List<Integer> getNumberList(int num, Supplier<Integer> sup){
List<Integer> resList = new ArrayList<>();
for(int i=0;i<num;i++){
Integer number = sup.get();
resList.add(number);
}
return resList;
}
//3、函数型接口:Function<T,R>
@Test
public void test3(){
String res = stringHandler("hello lambda", (s) -> s.toUpperCase());
System.out.println(res);
}
public String stringHandler(String str, Function<String,String> func){
return func.apply(str);
}
//4、断言型接口:Predicate<T>
@Test
public void test4(){
List<String> paramsLists = Arrays.asList("hello","world","lee","ren","home","haha");
List<String> list = filterStr(paramsLists, (s) -> s.length() < 5);
for (String s : list){
System.out.println(s);
}
}
public List<String> filterStr(List<String> list, Predicate<String> pre){
List<String> resList = new ArrayList<>();
for (String s : list){
if(pre.test(s)){
resList.add(s);
}
}
return resList;
}
}
二、Lambda方法引用
package com.lee.jdk.lambda;
import com.lee.jdk.Entity.Employee;
import org.junit.Test;
import java.io.PrintStream;
import java.util.Comparator;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Supplier;
/**
* 方法引用:若lambda体中的内容有方法已实现了,我们可以使用方法引用。
*
* [注意:引用的方法 要和实现的方法 的 参数列表 和 返回值 一致]
*
* 主要有三种语法格式:
* 对象::实例方法名
*
* 类::静态方法名
*
* 类::实例方法名(第一个参数是方法的调用者,第二个参数是方法的参数时 用这种语法格式如 a.equals(b))
*/
public class TestMethodRef {
//1.1、对象::实例方法名
@Test
public void test1(){
Consumer con = (x)-> System.out.println(x);
con.accept("abcdef");
System.out.println("===========================");
//System.out.println方法已经被实现了
PrintStream ps1 = System.out;
Consumer con1 = (x)->ps1.println(x);
con1.accept("123456");
System.out.println("===========================");
//System.out.println方法已经被实现了
PrintStream ps2 = System.out;
Consumer con2 = ps2::println;//或Consumer con2 = System.out::println;
con1.accept("a1b2c3d4e5f6");
}
//1.2、对象::实例方法名
@Test
public void test2(){
Employee emp = new Employee(1,"lee",25,19999d);
Supplier<String> sup1 = ()-> emp.getName();
System.out.println(sup1.get());;
System.out.println("============================");
Supplier<String> sup2 = emp::getName;
System.out.println(sup2.get());;
System.out.println("============================");
Supplier<Integer> sup3 = emp::getAge;
System.out.println(sup3.get());;
}
//1.3、类::静态方法名
@Test
public void test3(){
Comparator<Integer> comp1 = (x,y)->Integer.compare(x,y);
System.out.println(comp1.compare(10,12));
System.out.println("============================");
Comparator<Integer> comp2 = Integer::compare;
System.out.println(comp1.compare(10,12));
}
//1.4、类::实例方法名(第一个参数是方法的调用者,第二个参数是方法的参数时 用这种语法格式如 a.equals(b))
@Test
public void test4(){
BiPredicate<String,String> biPre1 = (x,y)->x.equals(y);
System.out.println(biPre1.test("abc","123"));
System.out.println("============================");
BiPredicate<String,String> biPre2 = String::equals;
System.out.println(biPre2.test("abc","abc"));
}
}
三、Lambda构造器引用
package com.lee.jdk.lambda;
import com.lee.jdk.Entity.Employee;
import org.junit.Test;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* 构造器引用
*
* [注意:需要调用的构造器的参数列表要与函数式接口中抽象方法的参数列表保持一致 ]
*
* 语法格式:
* ClassName::new
*/
public class TestConstructorRef {
//数组引用: String[]::new
//1、构造器引用 无参
@Test
public void test1(){
Supplier<Employee> sup1 = ()->new Employee();
System.out.println(sup1.get());
System.out.println("=======================");
Supplier<Employee> sup2 = Employee::new;
System.out.println(sup2.get());
}
//2、构造器引用 1个参数 或 多个参数
@Test
public void test2(){
Function<Integer,Employee> func = (x)->new Employee(x);
System.out.println(func.apply(1));
System.out.println("========================");
Function<Integer,Employee> func2 = Employee::new;
System.out.println(func2.apply(2));
System.out.println("========================");
BiFunction<Integer,String,Employee> biFunc = Employee::new; //(x,y)->new Employee(x,y);
System.out.println(biFunc.apply(3,"ren"));
}
}