Java的Lambda表达式

网页左边,向下滑有目录索引,可以根据标题跳转到你想看的内容
Lambda表达式是java8中的新特性(JDK1.8版本更新的)
  • 可以替代只有一个抽象函数的接口实现
  • 告别匿名内部类
  • 代码简介易懂
  • 提升集合、框架的迭代、遍历、过滤数据的操作
Lambda的特点
  • 函数式编程
  • 参数类型自动推断
  • 代码量少,简洁
  • 适用于任何有函数式接口的地方
函数式接口
就是有且只能有一个抽象方法的接口称为函数式接口
package com.company;

import java.util.ArrayList;

/**
 * 函数式接口,有且只能有一个抽象方法的的接口
 * 
 * 注解@FunctionalInterface 
 *      此注解作用就是标识一个接口为函数式接口,如果此接口中定义了两个以上的抽象方法,将会报错
 *      因为它不满足函数式接口特性,不能称之为函数式接口
 *      
 *      此注解可以不加,但是为了可读性,也为了让别人看到你的代码,知道你这是一个函数式接口,从而不会在你的接口中加抽象方法
 *      
 *      还是加上为好
 */
@FunctionalInterface
public interface Test {
    ArrayList<Integer> test(int[] arr, int flag);
}

在这里插入图片描述

一、函数式接口编程思想以及如何演变为lambda

仔细看下面这个接口,它只有一个抽象方法,一般这样的可以直接通过lambda表达式来实现,因为lambda表达式的作用就是可以当做方法的参数进行传递,既然它是一个函数,那么就可以做逻辑实现,它可以当参数传递,在不同场景实现为一个接口的抽象方法,实现不同逻辑
在这里插入图片描述

package com.company;

import java.util.ArrayList;

public interface Test {
    ArrayList<Integer> test(int[] arr, int flag);
}

在这里插入图片描述

package com.company;


import java.util.ArrayList;

/**
 * 客户端
 */
public class Main{

    public static void main(String[] args) {
        int arr[] = {1,2,3,4,5,6,7,8,9,10,11,12};
        ArrayList<Integer> list = new ArrayList<>();
        /**非接口编程思想,通常我们将逻辑封装到一个方法中,这里只做演示,就不单独写方法了*/
        //获取数组中>5的元素
        for (int i = 0;i < arr.length;i++){
            if(arr[i]>5){
                list.add(arr[i]);
            }
        }
        System.out.println(list.toString());
        list.clear();

        //获取数组中<5的元素
        for (int i = 0;i < arr.length;i++){
            if(arr[i]<5){
                list.add(arr[i]);
            }
        }
        System.out.println(list.toString());
        list.clear();

        /**
         * 可以看到上面的代码几乎重复,仅仅条件不一样,可维护和可优化的地方也不多
         * 接下来介绍
         * 接口式编程思想
         */
        //匿名实现接口方法,传递数组,并传递flag,如果flag为1表示大于,为其它值表示小于
        Test test = new Test() {

            @Override
            public ArrayList<Integer> test(int[] arr, int flag) {
                ArrayList<Integer> returnList = new ArrayList<>();

                for (int i = 0;i < arr.length;i++){
                    if(flag == 1? (arr[i]>5?true:false) : (arr[i]<5?true:false)){
                      returnList.add(arr[i]);
                    }
                }
                return returnList;
            }
        };
        //获取数组中>5的元素
        System.out.println(test.test(arr, 1).toString());

        //获取数组中<5的元素
        System.out.println(test.test(arr, 2).toString());

        /**
         * 可见上面接口式编程有了更好的可维护性和可优化性,还有很高的扩展性
         *
         * 但是依然有不足的地方
         *
         * 接下来介绍函数式思想,lambda表达式
         *
         *      Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。
         *
         *      Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。&&&&&&&&&&&&&&&&&&重点作用
         *
         *      使用 Lambda 表达式可以使代码变的更加简洁紧凑。
         *
         *
         *  lambda 表达式的语法格式如下:
         *   parameters:参数,expression:表达式,statements:代码块
         *
         * (parameters) -> expression
         * 或
         * (parameters) ->{ statements; }
         *
         *      // 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)
         */
        Test test1 = (int[] e,int q)->{
            ArrayList<Integer> returnList = new ArrayList<>();

            for (int i = 0;i < e.length;i++){
                if(q == 1? (e[i]>5?true:false) : (e[i]<5?true:false)){
                    returnList.add(e[i]);
                }
            }
            return returnList;
        };
        //获取数组中>5的元素
        System.out.println(test1.test(arr,1).toString());

        //获取数组中<5的元素
        System.out.println(test1.test(arr,2).toString());


        /**
         * 上面的例子只是帮助你们理解,lambda表达式真正方便之处,可以通过线程来体现
         */
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("我是通过匿名函数创建的Runnable接口实现");
            }
        }).start();

        //可以明显看出,lambda表达式更加简洁,并具有函数式接口编程的思想
        new Thread(()-> System.out.println("我是通过lambda创建的Runnable接口实现") ).start();


    }
}

二、接收lambda表达式的多种方式

随便介绍2个,剩下的都是相同的道理
在这里插入图片描述

package com.company;


import java.util.ArrayList;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * 客户端
 */
public class Main{

    public static void main(String[] args) {
        //接收lambda表达式的方式1,就是被函数式接口直接接收,此方式不限制输入和输出的数量,就是参数和返回值不限制
        Runnable runnable = ()-> System.out.println("我是runnable接口");
        runnable.run();

        //方式2使用Function接收 Function<参数类型,返回值类型>,1输入,1输出,表示必须传一个参数,返回一个值
        Function<String,Integer> f1 = (str)->{return str.length();};

        Integer strLength = f1.apply("测试字符串");

        System.out.println(strLength);

        //方式3使用Supplier<返回值类型> ,0输入,1输出,不能传参,必须返回一个值
        Supplier<String> supplier = ()->{return "你好";};
        Supplier<String> supplier2 = ()->"你好111";//写法2,()->值;表示直接返回值
        System.out.println(supplier.get()+supplier2.get());

		//方式4,BiFunction<参数类型,参数类型,返回值类型>,2输入1输出
        BiFunction<String,Integer,String> biFunction = (str,num)->str+num;

        System.out.println(biFunction.apply("1234", 5));
        
    }
}

三、方法的引用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.company;

import java.util.function.Supplier;

/**
 * 客户端
 */
public class Main{

    public Main(){
        System.out.println("构造方法");
    }

    static String getString(){
        return "aaaaaaaaa";
    }

    String getInst(){
        return "实例方法";
    }
    public static void main(String[] args) {
        //Supplier<返回类型> 1输出函数式接口,这是使用普通的lambda表达式
        Supplier<String> supplier1 = ()->"字符串1";
        System.out.println(supplier1.get());

        //使用方法实现lambda
//        Supplier<String> supplier2 = ()->getString(); 因为是在当前类的方法,可以直接通过方法名调用,一般不是在当前类,需要类名,也就是下面的用法
        Supplier<String> supplier2 = ()->Main.getString();
        System.out.println(supplier2.get());

        /**静态方法引用,类名::静态方法,底层就是用lambda表达式实现对应(args)->类名.静态方法名(参数表)**/
        supplier2 = Main::getString;
        System.out.println(supplier2.get());

        /**实例方法引用,实例名::实例方法,对应lambda为(args)->实例名.实例方法(args)**/
        Main main = new Main();

        supplier2 = main::getInst;
        System.out.println(supplier2.get());

         /**对象方法引用 类名::对象方法名  对应 (inst,args) -> 类名.对象方法(args)       和实例方法引用差不多
          *
          * 它可以使用任意对象的实例方法,比如String::compareToIgnoreCase
          * 
          * 但是使用比较麻烦,也用的比较少,就不多做介绍了
          * **/

         /**构造方法引用 类名::new   对应 (args)->new 类名(args)**/
        Supplier<Main> supplier3 =  Main::new;
        System.out.println(supplier3.get());
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

殷丿grd_志鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值