当前位置:   article > 正文

JDK8新特性之一Lambda表达式详解_jdk8 lamda表达式含义

jdk8 lamda表达式含义

 

一. 简介

Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码 像数据一样进行传递(行为参数化)。可以写出更简洁、更 灵活的代码。作为一种更紧凑的代码风格,使 Java的语言表达能力得到了提升.

我们可以把Lambda表达式理解为简洁地表示可传递的匿名函数的一种方式:它没有名称,但它 有参数列表、函数主体、返回类型,可能还有一个可以抛出的异常列表。

二、函数式编程思想概述

在数学中,函数简单可以理解为有输入量、输出量的一套计算方案,也即是"拿数据做操作"

面向对象思想强调的是"必须通过对象的形式来做事情"

函数式编程思想则是尽量去忽略面向对象的复杂语法,而是强调做什么,而不是以什么形式去做

现在我写的Lamdba表达式就是函数式编程思想的体现

三、体验Lambda表达式与面向对象编程的差异

创建一个线程的三种形式 ps:使用runnbale接口

3.1、普通方式

步骤为:定义一个类实现runnable接口——>创建该类对象——>入参

  1. public class MyRunnable implements Runnable {
  2. @Override
  3. public void run() {
  4. System.out.println("myThread");
  5. }
  6. }
  1. public static void main(String[] args) {
  2. //一、寻常方式
  3. Runnable runnable=new MyRunnable();
  4. Thread thread=new Thread(runnable);
  5. thread.start();

3.2、内部类的方式  Ps:无需具体实现接口的类

  1. //二、匿名内部类
  2. new Thread(new Runnable(){
  3. @Override
  4. public void run(){
  5. System.out.println("多线程程序启动了");
  6. }
  7. }).start();

3.3、Lambda表达式

  1. //lambda表达式
  2. new Thread(()->{
  3. System.out.println("多线程程序启动了");
  4. }).start();

四、Lamdba表达式的标准格式

(形式参数)——>{代码块}

():里面没有内容,可以看成是方式形式参数为空 Ps:后续会介绍有参数的该如何处理

——>:箭头后面表示要做的事情 Ps:可以看作指向的一个方法的实现

{}:这里包含着一段代码块,可以看成是方法体的具体实现内容


五、Lamdba使用前提

一、有一个接口作为形参

二、接口中有且只有一个抽象方法 

三、只要使用Lamdba表达式调用接口入参的方法则方法中的方法体会被执行

第三点可能难理解一些,我们可以写个Demo试试

步骤:定义一个接口,接口实现类,接口入参的方法

分别这么写,

  1. package com.company;
  2. public interface Eatable {
  3. void eat();
  4. }
  1. package com.company;
  2. public class EatableImpl implements Eatable {
  3. @Override
  4. public void eat() {
  5. System.out.println("为什么我没有被使用");
  6. }
  7. }
  1. package com.company;
  2. public class EatableDemo {
  3. private static void useEatable(Eatable eatable){
  4. eatable.eat(); //debug模式下运行第三点就很好理解了
  5. }
  6. public static void main(String[]args){
  7. useEatable(()->{
  8. System.out.println("您吃了没?");
  9. });
  10. }

六、抽象方法带参数但是无返回值该如何处理呢?

 

一样,用上述Demo,不过匿名内部类的方式不写,我们直接写Lamdba表达式

  1. public interface Eatable {
  2. void eat(String a,String b);
  3. }
  1. private static void useEatable(Eatable eatable){
  2. eatable.eat("1","2");
  3. System.out.println("我被用了");
  4. }
  5. public static void main(String[]args){
  6. //第一种方式
  7. useEatable((a,b)->{
  8. /*System.out.println(a+b);
  9. });

//第二种  不省略修饰符

useEatable((String a,String b)->{ /*System.out.println(a+b); });

}

只需要加入参数即可,如果抽象方法中只有一个参数呢?

  1. public interface Eatable {
  2. void eat(String a);
  3. }
  1. private static void useEatable(Eatable eatable){
  2. eatable.eat("1");
  3. System.out.println("我被用了");
  4. }
  5. public static void main(String[]args){
  6. //第一种 都省略,包括小括号
  7. useEatable(a->{
  8. /*System.out.println(a+b);*/
  9. });

//第二种 都不省略

  1. useEatable( (String a)->{
  2. /*System.out.println(a+b);*/
  3. });

//第三种,省略修饰符

  1. useEatable( (a)->{
  2. /*System.out.println(a+b);*/
  3. });

}

PS:想怎么写自己的自由,这个不限制

七:那么有返回值又有参数的抽象方法呢?

上面的拿过来,加个返回值,只需新增返回值即可

  1. public interface Eatable {
  2. String eat(String a);
  3. }
  1. private static void useEatable(Eatable eatable){
  2. eatable.eat("1");
  3. System.out.println("我被用了");
  4. }
  5. public static void main(String[]args){
  6. useEatable( (a)->{
  7. return a;
  8. });

八、总结下Lamdba表达式的写法

8.1 参数类型可以省略

例:useEatable( (a)->{ return a;});

8.2 多个参数的情况下参数类型要么都省略,要么都不省略

8.3 只有一个参数那么小括号也可以省略

useEatable( a->{ return a;});

8.4 如果代码块的语句只有一条可以省略大括号和小括号 PS但是不能有return, 如果想这么写就要把return也省了

useEatable(a->a);

九、使用Lamdba注意事项

9.1、使用Lamdba必须要有接口,并且要求接口中只有一个抽象方法

9.2、必须要有上下文环境,才能推导出Lamdba对应的接口

无故写一个Lamdba表达式编译器自己根本不晓得去哪里给你找

例: ()->System.out.println(); //绝对会报错,编译不通过

十、在实际工作中Lambda表示式一般会怎么使用呢?

在实际工作中结合Stream流的使用场景会很多,而能够使用Lambda表达式的接口大致可以分为以下四类

1. 消费型接口:Consumer< T> void accept(T t)有参数,无返回值的抽象方法;

2. 供给型接口:Supplier < T> T get() 无参有返回值的抽象方法;

3. 断定型接口: Predicate< T> boolean test(T t):有参,但是返回值类型是固定的boolean

4. 函数型接口: Function< T,R> R apply(T t)有参有返回值的抽象方法;


如果我们调用某一个方法,发现这个方法中需要传入的参数要求是一个函数式的接口,那么我们可以直接传入Lambda表达式。这些接口位于java.util.function包下,需要注意一下,java.util包和java.util.function包这两个包没有什么关系,切不可以为function包是java.util包下面的包。

除了这四个之外,在java.util.function包下还有很多函数式接口可供使用。

十一、Lamdba表达式的超简易模式——>方法引用符

当Lambda表达式满足某种条件的时候,使用方法引用,可以再次简化代码(有点语法糖的味道)

方法引用符主要可以分为一下几种场景使用

11.1构造引用,当Lambda表达式是通过new对象的方式来完成的,可以使用构造引用

Supplier<String> stringSupplier=String::new;

 

11.2 类名::实例方法

  1. TreeSet<String> set = new TreeSet<>(String::compareTo);
  2. set.add("Hello");
  3. set.add("isea_you");

11.3 对象::实例方法

set.forEach(System.out::println);

11.4 类名:;静态方法

  1. Stream<Double> stream = Stream.generate(Math::random);
  2. stream.forEach(System.out::println);

如果大家想系统的学习java8新特性建议去看看《JAVA8实战》这本书

转载请注明出处,掌声送给社会人

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/726784
推荐阅读
相关标签
  

闽ICP备14008679号