详解Java中的Lambda表达式

作者:rickiyang 时间:2021-08-17 00:06:00 

Java 目前已经出到13的版本,但是国内大部分公司应该都停留在 Java 8 的版本(不敢承担升级带来的风险)。在Java8中给我们带来了 Lambda表达式和Stream流式操作,提供了函数式编程和简化批处理操作。可能大家日常使用很多,但是很少去关注Lambda 和 Stream实现。本篇就带着大家一起关注这两块知识,搬好小板凳我们一起看电视。

什么是Lambda

简单来说,编程中提到的 lambda 表达式,通常是指需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数。

一般我们使用变量来进行赋值操作:

详解Java中的Lambda表达式

但是在 Java8 之前是没有提供将一个方法赋值给一个变量的操作:

详解Java中的Lambda表达式

在 JavaScript 中有 闭包的概念,所以 Java不甘落后,也去学习了人家,搞出了匿名函数的概念。

在Java 8里面,所有的Lambda的类型都是一个接口,而Lambda表达式本身,也就是”那段代码“,需要是这个接口的实现。这是我认为理解Lambda的一个关键所在,简而言之就是,Lambda表达式本身就是一个接口的实现。

基本语法:

(parameters) -> { expression or statements }

示例:


// 无参数, 返回1+2的结果
() -> 1+2;

// 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x;

// 接收2个参数(数字),返回表达式运算的结果
(x, y) -> x + y;

// 多个语句要用大括号包裹, 并且返回值要用return指明
(x, y) -> {
int result = x + y;
System.out.print(result);
return result;
};

Lambda表达式有如下约定:

  • 一个 Lambda 表达式可以有零个或多个参数;

  • 参数的类型既可以明确声明,也可以根据上下文来推断。例如:(int a)与(a)效果相同;

  • 所有参数需包含在圆括号内,参数之间用逗号相隔。例如:(a, b) 或 (int a, int b) 或 (String a, int b, float c);

  • 空圆括号代表参数集为空。例如:() -> 42;

  • 当只有一个参数,且其类型可推导时,圆括号()可省略。例如:a -> return a*a;

  • Lambda 表达式的主体可包含零条或多条语句;

  • 如果 Lambda 表达式的主体只有一条语句,花括号{}可省略。匿名函数的返回类型与该主体表达式一致;

  • 如果 Lambda 表达式的主体包含一条以上语句,则表达式必须包含在花括号{}中(形成代码块)。匿名函数的返回类型与代码块的返回类型一致,若没有返回则为空。

@FunctionalInterface 是 Java 8 新加入的一种接口,用于指明该接口类型声明是根据 Java 语言规范定义的函数式接口。Java 8 还声明了一些 Lambda 表达式可以使用的函数式接口,当你注释的接口不是有效的函数式接口时,可以使用 @FunctionalInterface 解决编译层面的错误。

根据定义,函数式接口只能有一个抽象方法,如果你尝试添加第二个抽象方法,将抛出编译时错误。例如:


@FunctionalInterface
public interface DoSomethingInterface {

void doSomeThing();

void doSomeThing1();

}

详解Java中的Lambda表达式

举一个简单使用的例子,首先定义一个接口:


@FunctionalInterface
public interface DoSomethingInterface<T> {

String doSomeThing(T t);

}

这个接口里面只能有一个函数,接口里是返回值为String类型的方法,那么下面使用它的时候就需要有返回值:


class MainTest{

public static void main(String[] args) {

DoSomethingInterface<String> t = str -> {
      return str;
    };
    String print = t.doSomeThing("print");
    System.out.println(print);

}
}

t就相当于是接口的具体实现,那么使用 t.doSomeThing("print")就会去调用 t 的匿名函数执行。从这段代码看,如果我们有一个抽象类的具体实现逻辑相对简单不用大段代码的时候,可以使用 Lambda 表达式去实现具体的逻辑,这样就不用new 多个类。

Java 8 内置4大核心函数式接口

大家日常使用的List,Map,肯定大量使用了Stream流式处理,在流式处理中大量使用了Lambda,比如List的foreach方法就使用了Lambda表达式。Java8中抽象出来4类基本的函数式接口,日常开发中我们其实也是可以使用的。

函数式接口参数类型返回类型用途
ConsumerTVoidvoid accept(T t) :将T 类型的参数应用于该方法
SupplierTTT get():返回类型为T 的对象
Function<T,R>TRR apply(T t):输出T类型的参数返回R类型的结果
PredicateTBooleanboolean test(T t): 确定类型为T 的参数是否满足test逻辑

以上4种类型是Java默认提供的Lambda类,开箱即用。

Consumer使用:


public void test(){
save(user, t->{ saveUser(t); });
}

public void save(User user, Consumer<User> consumer){
consumer.accept(user);
}

Supplier使用:


public void test(){

Config config = getConfig(t -> {
 return getAllConfig(t);
});

}

public Config getConfig(Supplier<Config> supplier) {
return supplier.get();
}

Function使用:


public void test(){
User user = getUser(t -> { return getUserByName(t); });
}

public User getUser(Function<String, User> function) {
return function.apply(t);
}

Predicate使用:


public void test(){
boolean b = checkStatus(user, t -> {
 return checkUserExist(t);
});

}

public boolean checkStatus(User user, Predicate<User> predicate) {
return predicate.test(user);
}

以上关于Lambda就介绍到这里,大家应该明白了它是干啥的了吧。闭包是不是也没有这么难懂呢!联想到List的foreach使用,大家有没有冲动想自己实现一个Lambda在日常开发中炫一把(如果别人看不懂,会打你的)。

来源:https://www.cnblogs.com/rickiyang/p/12052237.html

标签:JAVA,lambda,表达式
0
投稿

猜你喜欢

  • Apache Commons Math3探索之多项式曲线拟合实现代码

    2023-11-16 22:01:56
  • c# 通过内存映射实现文件共享内存的示例代码

    2023-03-02 12:15:35
  • Android中访问证书有问题的SSL网页的方法

    2023-11-20 10:22:00
  • c# 基于任务的异步编程模式(TAP)的异常处理

    2023-08-03 15:44:06
  • springboot自定义Starter过程解析

    2023-07-24 22:24:55
  • 使用Java将一个List运用递归转成树形结构案例

    2021-10-14 15:18:30
  • Java运算符从见过到掌握上

    2022-09-08 02:12:43
  • MediaPlayer音频与视频播放方法示例介绍

    2021-07-03 17:36:48
  • OpenCV实现图像背景虚化效果原理详解

    2021-12-06 02:25:59
  • seata springcloud整合教程与遇到的坑

    2023-09-19 03:11:06
  • springBoot controller,service,dao,mapper,model层的作用说明

    2022-02-28 15:38:49
  • Android实现实时通信示例

    2022-12-27 00:59:55
  • Java判断字符串是否是整数或者浮点数的方法

    2022-04-30 10:06:20
  • 解析C# 程序结构

    2021-11-15 05:22:59
  • 深入浅析hbase的优点

    2021-08-06 19:27:58
  • Java Maven构建工具中mvnd和Gradle谁更快

    2022-02-15 04:39:52
  • java设计模式-单例模式实现方法详解

    2022-02-15 13:56:01
  • Mybatis实现增删改查

    2022-05-26 22:00:20
  • Java8中Optional类的使用说明

    2023-07-25 13:31:32
  • Kotlin 编程三分钟入门

    2021-06-27 13:22:35
  • asp之家 软件编程 m.aspxhome.com