Java8的Lambda表达式你真的会吗

 更新时间:2021年01月04日 08:54:30   作者:天乔巴夏丶  
这篇文章主要介绍了Java8的Lambda表达式你真的会吗,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

理解Lambda

Lambda表达式可以是一段可以传递的代码,它的核心思想是将面向对象中的传递数据变成传递行为,也就是行为参数化,将不同的行为作为参数传入方法。

随着函数式编程思想的引进,Lambda表达式让可以用更加简洁流畅的代码来代替之前冗余的Java代码。

口说无凭,直接上个例子吧。在Java8之前,关于线程代码是这样的:

class Task implements Runnable{

 @Override
 public void run() {
  System.out.println("Java8 之前 实现Runnable接口中的run方法");
 }
}
Runnable t = new Task();

我们定义了一个Task类,让它实现Runnable接口,实现仅有的run方法,我们希望执行的线程体虽然只有一句话,但我们仍然花了大量大代码去定义。为了简化,我们可以采用匿名内部类的方式:

Runnable taskBeforeJava8 = new Runnable() {
 @Override
 public void run() {
  System.out.println("Java8 之前的写法, 传入匿名类");
 }
};

但是,其实还是不够简洁,我们用Lambda的写法是这样的:

// java8 之后
Runnable taskAfterJava8 = () -> System.out.println("Java8 之后的写法,lambda表达式");

我们仅仅使用()->就完成了这件事,是不是非常简洁呢?如果你觉得虽然Lambda写法简洁,但是它的规则让人摸不着头脑,那就跟着我接下去学叭。

基础语法

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

parameters代表变量,可以为空,可以为单,可以为空,你能想到的方式他都可以。

action是实现的代码逻辑部分,可以是一行代码expression,也可以是一个代码片段statements。如果是代码片段,需要加上{}

下面是一些合法的示例,你可以看看有没有掌握:

表达式 描述
() -> 1024 不需要参数,返回值为1024
x -> 2 * x 接收参数x,返回其两倍
(x, y) -> x - y 接收两个参数,返回它们的差
(int x, int y) -> x + y 接收两个int类型参数,返回他们的和
(String s) -> print(s) 接收一个String对象,并打印

函数式接口

@FunctionalInterface // 此注解作用的接口 只能拥有一个抽象方法
public interface Runnable {
 public abstract void run();
}

在这里,@FunctionalInterface注解是非必须的,有点类似于@Override,起强调作用,如果你的接口标注该注解,却没有遵循它的原则,编译器会提示你修改。

常用的函数式接口

JDK原生为我们提供了一些常用的函数式编程接口,让我们在使用他们编程时,不必关心接口名,方法名,参数名,只需关注它的参数类型,参数个数,返回值。

接口 参数 返回值 类别 示例
Consumer T void 消费型接口 打印输出某个值
Supplier None T 供给型接口 工厂方法获取一个对象
Function T R 函数型接口 获取传入列表的总和
Predicate T boolean 断言型接口 判断是否以summer为前缀

消费型接口

@FunctionalInterface // 此注解作用的接口 只能拥有一个抽象方法
public interface Runnable {
 public abstract void run();
}

供给型接口

/**
  * 供给型接口, 无参数,返回T
  */
 public static void supplierTest() {
  Supplier<Object> supplier = () -> new Object();
  System.out.println(supplier.get());
 }

断言型接口

 /**
  * 断言型 传入参数T ,返回boolean
  */
 public static void predicateTest() {
  Predicate<String> predicate = name -> name.startsWith("summer");
  System.out.println(predicate.test("summerday"));
 }

函数型接口

 /**
  * 函数型接口 传入T 返回R
  */
 public static void functionTest() {
  List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
  Function<List<Integer>, Integer> function = num -> {
   int res = 0;
   for (int n : list) {
    res += n;
   }
   return res;
  };
  Integer num = function.apply(list);
  System.out.println(num);
 }

方法引用

方法引用可以看作特定Lambda表达式的快捷写法,主要分为以下两种:

  • 指向静态方法的方法引用
  • 指向现有对象的实例方法的方法引用
/**
 * 方法引用
 * 1. 指向静态方法的方法引用
 * 2. 指向现有对象的实例方法的方法引用
 *
 * @author Summerday
 */
public class MethodReferenceTest {
	
 public static List<String> getList(List<String> params, Predicate<String> filter) {
  List<String> res = new LinkedList<>();
  for (String param : params) {
   if (filter.test(param)) {
    res.add(param);
   }
  }
  return res;
 }
 // 静态方法
 public static boolean isStartWith(String name) {
  return name.startsWith("sum");
 }

 public static void main(String[] args) {
  List<String> params = Arrays.asList("summerday","tqbx","天乔巴夏","summer","");
  //静态方法的方法引用 getList(params, name -> MethodReferenceTest.isStartWith(name));
  List<String> list = getList(params, MethodReferenceTest::isStartWith);
  System.out.println(list);
  
  // 指向现有对象的实例方法的方法引用 getList(params, name -> name.isEmpty());
  List<String> sum = getList(params, String::isEmpty);
  System.out.println(sum);
  
 }
}

数组引用

/**
 * 数组引用
 * @author Summerday
 */
public class ArrayReferenceTest {

 public static void main(String[] args) {
  // 普通lambda
  Function<Integer,String[]> fun1 = x -> new String[x];
  String[] res1 = fun1.apply(10);
  System.out.println(res1.length);

  // 数组引用写法
  Function<Integer,String[]> fun2 = String[]::new;
  String[] res2 = fun2.apply(10);
  System.out.println(res2.length);

 }
}

构造器引用

/**
 * 构造器引用
 * @author Summerday
 */
public class ConstructorReferenceTest {

 public static void main(String[] args) {

  // 普通lambda
  Supplier<User> sup = () -> new User();

  // 构造器引用
  Supplier<User> supplier = User::new;
  User user = supplier.get();
  System.out.println(user);
 }

}

class User{

}

总结

  •  lambda表达式没有名称,但有参数列表,函数主体,返回类型,可能还有一个可以抛出的异常的列表。
  • lamda表达式让你可以将不同的行为作为参数传入方法。
  • 函数式接口是仅仅声明了一个抽象方法的接口。只有在接受函数式接口的地方才可以使用lambda表达式。
  • lambda表达式允许你直接内联,为函数式接口的抽象方法提供实现,并将整个表达式作为函数式接口的一个实例。
  • Java8自带了一些常用的函数式接口,包括Predicate,Function,Supplier,Consumer,BinaryOperator
  • 方法引用让你重复使用现有的方法实现并直接传递他们:Classname::method

到此这篇关于Java8的Lambda表达式你真的会吗的文章就介绍到这了,更多相关Java8的Lambda表达式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 前端发送的请求Spring如何返回一个文件详解

    前端发送的请求Spring如何返回一个文件详解

    这篇文章主要给大家介绍了关于前端发送的请求Spring如何返回一个文件的相关资料,文中通过代码介绍的非常详细,对大家的学习或者工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2024-09-09
  • Quarkus集成Dubbo服务Rpc远程通讯框架整合

    Quarkus集成Dubbo服务Rpc远程通讯框架整合

    这篇文章主要为大家介绍了Quarkus集成Dubbo服务Rpc远程通讯框架的整合,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-02-02
  • OpenCV Java实现人脸识别和裁剪功能

    OpenCV Java实现人脸识别和裁剪功能

    这篇文章主要为大家详细介绍了OpenCV Java实现人脸识别和裁剪功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-05-05
  • java.lang.Runtime.exec() Payload知识点详解

    java.lang.Runtime.exec() Payload知识点详解

    在本篇文章里小编给大家整理的是一篇关于java.lang.Runtime.exec() Payload知识点相关内容,有兴趣的朋友们学习下。
    2020-03-03
  • java存储以及java对象创建的流程(详解)

    java存储以及java对象创建的流程(详解)

    下面小编就为大家带来一篇java存储以及java对象创建的流程(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • 浅谈hibernate中懒加载禁用操作

    浅谈hibernate中懒加载禁用操作

    这篇文章主要介绍了浅谈hibernate中懒加载禁用操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-10-10
  • SpringBoot整合Javamail实现邮件发送功能

    SpringBoot整合Javamail实现邮件发送功能

    邮件发送是一个很普遍的功能,springboot整合了相关的starter,本文给大家介绍了可以实现一个简单的邮件发送功能的实例,文中通过代码给大家介绍的非常详细,感兴趣的朋友可以参考下
    2023-12-12
  • Java中BigDecimal的舍入模式解析(RoundingMode)

    Java中BigDecimal的舍入模式解析(RoundingMode)

    这篇文章主要介绍了Java中BigDecimal的舍入模式解析(RoundingMode),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • SpringBoot2线程池定义使用方法解析

    SpringBoot2线程池定义使用方法解析

    这篇文章主要介绍了SpringBoot2线程池定义使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • Mybatis-Plus自动填充的实现示例

    Mybatis-Plus自动填充的实现示例

    这篇文章主要介绍了Mybatis-Plus自动填充的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08

最新评论