一,Lambda表达式语法

1.语法结构

(parameters) -> expression
或
(parameters) ->{ statements;}

语法形式为 () -> {}:

() 用来描述参数列表,如果有多个参数,参数之间用逗号隔开,如果没有参数,留空即可;

-> 读作(goes to),为 lambda运算符 ,固定写法,代表指向动作;

{} 代码块,具体要做的事情,也就是方法体内容;

2.特征

可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。

可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。

可选的大括号:如果主体包含了一个语句,就不需要使用大括号。

可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。

3.小例子

// 1. 不需要参数,返回值为 5  
() -> 5  
// 2. 接收一个参数(数字类型),返回其2倍的值  
x -> 2 * x  
// 3. 接受2个参数(数字),并返回他们的差值  
(x, y) -> x – y  
// 4. 接收2个int型整数,返回他们的和  
(int x, int y) -> x + y  
// 5. 接受一个 string 对象,并在控制台打印,不返回任何
值(看起来像是返回void)  
(String s) -> System.out.print(s)

二,Lambda入门案例

1.定义接口函数

/**
 * 无返回值,无参数
*/
 @FunctionalInterface
 interface NoReturnNoParam{
 void method();
 }
 /**
 * 无返回值,有一个参数
*/
 @FunctionalInterface
 interface NoReturnOneParam{
 void method(int a);
 }
 /**
 * 无返回值,有多个参数
*/
 @FunctionalInterface
 interface NoReturnMultiParam{
 void method(int a,int b);
 }
 /**
 * 有返回值,无参数
*/
 @FunctionalInterface
 interface ReturnNoParam{
 int method();
 }
 /**
 * 有返回值,有一个参数
*/
 @FunctionalInterface
 interface ReturnOneParam{
 int method(int a);
 }
 /**
 * 有返回值,有多个参数
*/
 @FunctionalInterface
 interface ReturnMultiParam{
 int method(int a,int b);
 }

2.实现函数接口

public static void main(String[] args) {
 /**
 * 无返回值,无参数
*/
 NoReturnNoParam noReturnNoParam = ()->{
 System.out.println("NoReturnNoParam");
    };
 noReturnNoParam.method();
 /**
 * 无返回值,有一个参数
*/
 NoReturnOneParam noReturnOneParam = (int 
a)->{
 System.out.println("NoReturnOneParam 
"+a);
    };
 noReturnOneParam.method(10);
 /**
 * 无返回值,有多个参数
*/
 NoReturnMultiParam noReturnMultiParam = 
(int a, int b)->{
 System.out.println("NoReturnMultiParam 
"+a+"\t"+b);
    };
 noReturnMultiParam.method(10,20);
 /**
 * 有返回值,无参数
*/
 ReturnNoParam returnNoParam = ()->{
 System.out.print("ReturnNoParam ");
 return 10;
    };
 System.out.println(returnNoParam.method());
/**
 * 有返回值,有一个参数
*/
 ReturnOneParam returnOneParam = (int a)->{
 System.out.print("ReturnOneParam ");
 return a;
    };
 System.out.println(returnOneParam.method(10));
 /**
 * 有返回值,有多个参数
*/
 ReturnMultiParam returnMultiParam = (int a 
,int b)->{
 System.out.print("ReturnMultiParam ");
 return a+b;
    };
 System.out.println(returnMultiParam.method(10,
 20));
 }

3.Lambda语法简化

/**
 * 无返回值,无参数
*/
 /* NoReturnNoParam noReturnNoParam = ()->{
System.out.println("NoReturnNoParam");
 };*/
 /**
 * 简化版
*/
 NoReturnNoParam noReturnNoParam = ()-> 
System.out.println("NoReturnNoParam");
 noReturnNoParam.method();
 /**
 * 无返回值,有一个参数
*/
 /* NoReturnOneParam noReturnOneParam = (int 
a)->{
 System.out.println("NoReturnOneParam 
"+a);
 };*/
 /**
 * 简化版
*/
 NoReturnOneParam noReturnOneParam = a -> 
System.out.println("NoReturnOneParam "+a);
 noReturnOneParam.method(10);
 /**
 * 无返回值,有多个参数
*/
 /* NoReturnMultiParam noReturnMultiParam = 
(int a, int b)->{
 System.out.println("NoReturnMultiParam 
"+a+"\t"+b);
 };*/
NoReturnMultiParam noReturnMultiParam =
 (a,b)-> System.out.println("NoReturnMultiParam 
"+a+"\t"+b);
 noReturnMultiParam.method(10,20);
 /**
 * 有返回值,无参数
*/
 /* ReturnNoParam returnNoParam = ()->{
 System.out.print("ReturnNoParam ");
 return 10;
 };*/
 /**
 * 简化版
*/
 ReturnNoParam returnNoParam = ()->10+20;
 System.out.println(returnNoParam.method());
 /**
 * 有返回值,有一个参数
*/
 /*  ReturnOneParam returnOneParam = (int a)->
 {
 System.out.print("ReturnOneParam ");
 return a;
 };*/
 /***
 * 简化版
*/
 ReturnOneParam returnOneParam = a->a;
 System.out.println(returnOneParam.method(10));
/**
 * 有返回值,有多个参数
*/
 /*ReturnMultiParam returnMultiParam = (int 
a ,int b)->{
 System.out.print("ReturnMultiParam ");
 return a+b;
 };*/
 /**
 * 简化版
*/
 ReturnMultiParam returnMultiParam = (a ,b)
>a+b;
 System.out.println(returnMultiParam.method(10,
 20));
 }

三,Lambda使用

1.Lambda表达式引用方法

有时候我们不是必须使用Lambda的函数体定义实现,我们可以利用 lambda表达式指向一个已经存在的方法作为抽象方法的实现。

01。要求

参数的个数以及类型需要与函数接口中的抽象方法一致。

返回值类型要与函数接口中的抽象方法的返回值类型一致。

02.语法

方法归属者::方法名 静态方法的归属者为类名,非静态方法归属者为该对象的引用。

03.案例

/**
 * 无返回值,无参数
*/
 @FunctionalInterface
 interface NoReturnNoParam{
 void method();
 }
 /**
 * 无返回值,有一个参数
*/
 @FunctionalInterface
 interface NoReturnOneParam{
 void method(int a);
 }
 /**
 * 无返回值,有多个参数
*/
 @FunctionalInterface
 interface NoReturnMultiParam{
 void method(int a,int b);
 }
/**
 * 有返回值,无参数
*/
 @FunctionalInterface
 interface ReturnNoParam{
 int method();
 }
 /**
 * 有返回值,有一个参数
*/
 @FunctionalInterface
 interface ReturnOneParam{
 int method(int a);
 }
 /**
 * 有返回值,有多个参数
*/
 @FunctionalInterface
 interface ReturnMultiParam{
 int method(int a,int b);
 }
 public class Test {
 public static void main(String[] args) {
 /**
 * 无返回值,无参数
*/
 /* NoReturnNoParam noReturnNoParam = ()
>{
 System.out.println("NoReturnNoParam");
};*/
 /**
 * 简化版
*/
 NoReturnNoParam noReturnNoParam = ()-> 
System.out.println("NoReturnNoParam");
 noReturnNoParam.method();
 /**
 * 无返回值,有一个参数
*/
 /* NoReturnOneParam noReturnOneParam = 
(int a)->{
 System.out.println("NoReturnOneParam "+a);
 };*/
 /**
 * 简化版
*/
 NoReturnOneParam noReturnOneParam = a 
> System.out.println("NoReturnOneParam "+a);
 noReturnOneParam.method(10);
 /**
 * 无返回值,有多个参数
*/
 /* NoReturnMultiParam noReturnMultiParam 
= (int a, int b)->{
 System.out.println("NoReturnMultiParam 
"+a+"\t"+b);
 };*/
NoReturnMultiParam noReturnMultiParam =
 (a,b)-> System.out.println("NoReturnMultiParam 
"+a+"\t"+b);
 noReturnMultiParam.method(10,20);
 /**
 * 有返回值,无参数
*/
 /* ReturnNoParam returnNoParam = ()->{
 System.out.print("ReturnNoParam ");
 return 10;
 };*/
 /**
 * 简化版
*/
 ReturnNoParam returnNoParam = ()
>10+20;
 System.out.println(returnNoParam.method());
 /**
 * 有返回值,有一个参数
*/
 /*  ReturnOneParam returnOneParam = (int 
a)->{
 ");
 System.out.print("ReturnOneParam 
return a;
 };*/
 /***
 * 简化版
*/
ReturnOneParam returnOneParam = a->a;
 System.out.println(returnOneParam.method(10));
 /**
 * 有返回值,有多个参数
*/
 /*ReturnMultiParam returnMultiParam = 
(int a ,int b)->{
 System.out.print("ReturnMultiParam 
");
 return a+b;
 };*/
 /**
 * 简化版
*/
 ReturnMultiParam returnMultiParam = (a 
,b)->a+b;
 System.out.println(returnMultiParam.method(10,
 20));
    }
 /**
 * 要求:
* 1,参数的个数以及类型需要与函数接口中的抽象方法一
致。
一致。
* 2,返回值类型要与函数接口中的抽象方法的返回值类型
* @param a
 * @return
 */
 public static int doubleNum(int a){
 return 2*a;
    }
 public int addTwo(int a){
 return a+2;
    }
}
public class Test2 {
 public static void main(String[] args) {
 ReturnOneParam returnOneParam = 
Test::doubleNum;
 int value = returnOneParam.method(10);
 System.out.println(value);
 Test test = new Test();
 ReturnOneParam returnOneParam1 = 
test::addTwo;
 int value2 = 
returnOneParam1.method(10);
 System.out.println(value2);
    }
 }

2.Lambda表达式创建线程

public class Test3 {
 public static void main(String[] args) {
System.out.println(Thread.currentThread().getN
 ame()+" 开始");
 new Thread(()->{
 for(int i=0;i<20;i++){
 try {
 Thread.sleep(500);
                } 
catch (InterruptedException 
e) {
 e.printStackTrace();
                }
 System.out.println(Thread.currentThread().getN
 ame()+" "+i);
            }
        },"Lambda Thread ").start();
 System.out.println(Thread.currentThread().getN
 ame()+" 结束");
    }
 }

3.Lambda表达式的闭包问题

什么是闭包

闭包的本质就是代码片断。所以闭包可以理解成一个代码片断的引用。在Java中匿名内部类也是闭包的一种实现方式。

在闭包中访问外部的变量时,外部变量必须是final类型,虚拟机会帮我们加上 final 修饰关键字。

public class Test4 {
 public static void main(String[] args) {
 final int num  =10;
 NoReturnNoParam noReturnNoParam = ()->System.out.println(num);
 noReturnNoParam.method();
    }
 }

四,常用函数接口

1.Consumer接口的使用

Consumer 接口是JDK为我们提供的一个函数式接口,该接口也被称为消费型接口。

遍历集合

我们可以调用集合的 public void forEach(Consumer<?super E?> action) 方法,通过 lambda 表达式的方式遍历集合中的元素。以下是 Consumer 接口的方法以及遍历集合的操作。

public class Test4 {
 public static void main(String[] args) {
 List<String> list = new ArrayList<>();
 list.add("a");
 list.add("b");
 list.add("c");
 list.add("d");
 list.forEach(System.out::println);
    }
 }

2.Predicate接口的使用

Predicate 是 JDK 为我们提供的一个函数式接口,可以简化程序的编写。

删除集合中的元素

我们通过public boolean removeIf(Predicate<Predicate<?super E> filter)方 法来删除集合中的某个元素,

public class Test5 {
 public static void main(String[] args) {
 List<String> list = new ArrayList<>();
 list.add("a");
 list.add("b");
 list.add("c");
 list.add("d");
 list.removeIf(ele->ele.equals("b"));
 list.forEach(System.out::println);
    }
 }

3.Compartor接口的使用

Comparator是 JDK 为我们提供的一个函数式接口,该接口为比较器接口

元素排序

之前我们若要为集合内的元素排序,就必须调用 sort 方法,传入比较器重写 compare 方法的比较器对象,现在我们还可以使用 lambda 表达式来简化代码。

public class Test7 {
 public static void main(String[] args) {
 List<String> list = new ArrayList<>();
 list.add("a");
 list.add("d");
 list.add("b");
 list.add("c");
 list.sort((o1,o2)->o1.compareTo(o2));
 list.forEach(System.out::println);
    }
 }

五,Stream流介绍

1.Stream流简介

Stream是数据渠道,用于操作数据源所生成的元素序列,它可以实现对集合的复杂操作,例如过滤、排序和映射等。Stream不会改变源对象,而是返回一个新的结果集

2.Stream流的生成方式

生成流:通过数据源(集合、数组等)创建一个流。

中间操作:一个流后面可以跟随零个或者多个中间操作,其目的主要是打开流,做出某种程度的数 据过滤/映射,然后返回一个新的流,交给下一个操作使用。

终结操作:一旦执行终止操作,就执行中间的链式操作,并产生结果

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐