首页 > 编程语言 >Java Lambda表达式应用说明

Java Lambda表达式应用说明

时间:2023-09-14 23:32:32浏览次数:34  
标签:Java System test println 返回值 Lambda 表达式 out

Lambda简介

  • Lambda 可定义为一种简洁、可传递的匿名函数,它是推动Java 8发布的最重要新特性
  • Lambda 本质上是一个函数,虽然它不属于某个特定的类,但具备参数列表、函数主体、返回类型,甚至能够抛出异常
  • Lambda 是匿名的,它没有具体的函数名称
  • Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)
  • Lambda 可以使代码变的更加简洁

Lambda基本语法

基本语法: (parameters) -> expression 或 (parameters) ->{ statements; }

  • parameters:类似方法中的形参列表,这里的参数是函数式接口里的参数。
  • ->:可以理解为被用于
  • 方法体:可以是表达式,也可以是代码,是函数式接口里方法的实现。

代码示例:

// 返回给定字符串的长度(隐含return语句) 
(String str) -> str.length()

// 始终返回233的无参方法(隐含return语句) 
() -> 233

// 返回当前用户是否年龄大于20岁,返回一个boolean值(隐含return语句) 
(User user) -> user.getAge() > 20

// 包含多行表达式,需用花括号括起来,并使用return关键字返回
(int x, int y) -> { 
    int z = x * y; 
    return x + z; 
}

使用Lambda与传统写法对比

public class testMain {
    //执行Runnable方法
    public static void process(Runnable r){
        r.run();
    }

    public static void main(String[] args) {
        //使用Lambda
        Runnable r1=()-> System.out.println("Hello Lambda");
        //传统匿名类
        Runnable r2 = new Runnable(){
            public void run(){
                System.out.println("Hello World 2");
            }
        };
        //打印 "Hello World 1"
        process(r1);
        //打印 "Hello World 2"
        process(r2);
        //利用直接传递的 Lambda 打印 "Hello World 3"
        process(() -> System.out.println("Hello World 3"));
    }
}

Lambda表达式的基本使用

@FunctionalInterface
interface NoParameterNoReturn {
    //注意:只能有一个抽象方法
    void test();
}

//无返回值一个参数
@FunctionalInterface
interface OneParameterNoReturn {
    void test(String a);
}

//无返回值多个参数
@FunctionalInterface
interface MoreParameterNoReturn {
    void test(int a, int b);
}

//有返回值无参数
@FunctionalInterface
interface NoParameterReturn {
    int test();
}

//有返回值一个参数
@FunctionalInterface
interface OneParameterReturn {
    String test(String a);
}

//有返回值多参数
@FunctionalInterface
interface MoreParameterReturn {
    int test(int a, int b);
}

具体使用见以下示例代码

//没有参数没有返回值
        NoParameterNoReturn noParameterNoReturn=()-> System.out.println("noParameterNoReturn");
        noParameterNoReturn.test();
        //没有参数但是有返回值
        NoParameterReturn noParameterReturn=()->40;
        System.out.println("noParameterReturn: "+ noParameterReturn.test());
        //一个参数没有返回值
        OneParameterNoReturn oneParameterNoReturn=(name)-> System.out.println("Hello :" +name);
        oneParameterNoReturn.test("张三");
        //一个参数和返回值
        OneParameterReturn oneParameterReturn=(name)-> "Hello: "+name;
        System.out.println("oneParameterReturn : "+ oneParameterReturn.test("李四") );
        //多参数没有返回值
        MoreParameterNoReturn moreParameterNoReturn=(a,b)-> System.out.println("a+b= "+(a+b));
        moreParameterNoReturn.test(10,20);
        //多参数和返回值
        MoreParameterReturn moreParameterReturn=(a,b)-> a+b;
        System.out.println("moreParameterReturn: "+ moreParameterReturn.test(20,40));

输出结果如下:

Java Lambda表达式应用说明_解决方案

Lambda 受检异常处理

简介

  • Lambda表达式利用函数式编程提供精简的方式表达行为。
  • 然而,JDK函数式接口没有很好地处理异常,使得处理异常代码非常臃肿和麻烦。
  • 接下来我们探讨 Lambda表达式中处理异常的解决方案

代码示例

以一个简单代码为例,将10与List中每个元素相除并打印出结果

List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5, 6);
        integers.forEach(i -> System.out.println(50 / i));

这样看是不会有问题的,代码简洁。但是如果List中包含元素0,那么就会抛出异常:ArithmeticException: / by zero有经验的小伙伴可能会立马给出解决方案,使用传统的try-catch来处理异常,代码如下:

List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5, 6, 0);
        integers.forEach(i -> {
            try {
                System.out.println(10 / i);
            } catch (ArithmeticException e) {
                System.err.println( "Arithmetic Exception occured : " + e.getMessage());
            }
        });

使用try-catch解决了问题,但是失去了lambda表达式的精简,代码变得臃肿,想必并不是完美的解决方案。对于一些强迫症老哥来说,这种代码是绝对不能存活的,所以我们需要如下的解决方案。

解决方案

我们将会对抛出异常的函数进行包装,使其不抛出受检异常如果一个FunctionInterface的方法会抛出受检异常(比如Exception),那么该FunctionInterface便可以作为会抛出受检异常的 Lambda 的目标类型。我们定义如下一个FunctionInterface

@FunctionalInterface
interface UncheckedFunction<T, R> {
    R apply(T t) throws Exception;
}

首先我们定义一个Try类,它的consumerWrapper方法:

public class Try {

    public static <T, E extends Exception> Consumer<T> consumerWrapper(Consumer<T> consumer, Class<E> clazz)  {

        return i -> {
            try {
                consumer.accept(i);
            } catch (Exception ex) {
                try {
                    E exCast = clazz.cast(ex);
                    System.err.println(
                            "Exception occured : " + exCast.getMessage());
                } catch (ClassCastException ccEx) {
                    throw ex;
                }
            }
        };
    }
}

然后在原先的代码中,我们使用Try.consumerWrapper方法来对会抛出受检异常的 Lambda 进行包装:

List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5, 6, 0);
        integers.forEach(
                Try.consumerWrapper(
                        i -> System.out.println(50 / i),
                        ArithmeticException.class));

Java Lambda表达式应用说明_System_02

此时,我们便可以选择是否去捕获异常(RuntimeException)。这种解决方法下,我们一般不关心抛出异常的情况 。比如自己写的小例子,抛出了异常程序就该终止;或者你知道这个 Lambda 确实 100% 不会抛出异常。

标签:Java,System,test,println,返回值,Lambda,表达式,out
From: https://blog.51cto.com/maguobin/7475565

相关文章

  • 计算器思想-中缀表达式转化为后缀表达式
    计算机思维和人的思维的不同对于一个算式3+2*(4-3)/5人的思维是根据括号和符号优先级,优先计算括号中的数据,在进行乘法和除法,在处理加法运算但是计算机的思维是线性的,计算机会按照算式的前后顺序,从前往后进行运算,这样会导致运算结果错误计算机如何套用人的运算思维想要让计算机......
  • java的jdbc插入的时候,遇到null情况报错问题
    分析原因:在执行SQL时MyBatis会自动通过对象中的属性给SQL中参数赋值,它会自动将Java类型转换成数据库的类型。而一旦传入的是null它就无法准确判断这个类型应该是什么,就有可能将类型转换错误,从而报错。解决办法:参数增加jdbcType标识数据类型。(注意:这时候参数{}前统一用#)<inser......
  • Java学习_009_for循环
    循环结构:组成:1.初始化语句:用于表示循环开启时的起始状态,简单说就是循环开始的时候是什么样子;2.条件判断语句:用于表示循环反复执行的条件,简单说就是判断循环是否能够一直执行下去;3.循环体语句:用于表示循环反复执行的内容,简单说就是循环反复执行的事情;4.条件控制语句:用于表示循......
  • Java学习_007_Switch语句
    需求:输入一到七的任意一个数,输出该数字对应的星期数。使用Switch语句:1importjava.util.Scanner;23publicclassMain{4publicstaticvoidmain(String[]args){5Scannersc=newScanner(System.in);6System.out.println("请输入一......
  • java---方法
    方法对一段功能代码进行集中管理,每个同学在某一时刻只做一件事情。单一职责。5.1方法的分类构造方法在创建对象时自动调用成员方法使用对象进行调用静态方法static使用类名进行调用()-->代表的就是方法5.2方法的创建语法:访问修饰符[static]返回值类型方法名([形式参......
  • Java数组遍历
    publicclassbianli{publicstaticvoidmain(String[]args){int[]arr={11,22,33,44,55};printArray(arr);}publicstaticvoidprintArray(int[]arr){System.out.print("[");......
  • 解密MySQL中强大的武器——REGEXP正则表达式
    家人们,今天我来为大家介绍一项在MySQL中非常强大的武器——REGEXP正则表达式。MySQL作为一款广泛使用的关系型数据库管理系统,其内置的REGEXP关键字为我们提供了强大的正则表达式功能,使得我们可以更加灵活和高效地进行数据匹配和处理。以下是一些常见的用法和语法规则来详解REG......
  • Java学习_006_考试奖励
    需求:小明期末考试,小明的爸爸对他说,会根据他不同的期末考试成绩,送他不同的礼物,假如你可以控制小明的得分,请用程序实现小明到底该获得什么样的礼物,并在控制台输出。     奖励:95-100-----山地自行车一辆;  90-94------游乐场游玩一次;80-89----......
  • HBase学习5(HBase java编程:创建项目,创建删除表,数据增删改查)
    1.准备工作1.1创建IDEAMaven项目其中名字为hbase_op,groupid为cn.itcast然后导入pom依赖<repositories><!--代码库--><repository><id>aliyun</id><url>http://maven.aliyun.com/nexus/content/groups/public/</url>&l......
  • 本机hadoop version命令报错--JAVA_HOME is not set问题的解决
    问题描述输入hadoopversion命令显示JAVA_HOME没有配置,但是本机的jdk配置正常!问题解决编辑hadoop/etc/hadoop目录下的hadoop-env.cmd文件:将JAVA_HOME的值换成本机的绝对路径;保存退出,再次尝试:......