【0003】java中关于匿名表达式与lambda表达式关系的理解

【【0003】java中关于匿名表达式与lambda表达式关系的理解:


知识点背景:


今天下午看代码,有一块写不出来了,我知道那是lambda表达式代码进行简化代码,但是自己去写简化代码又忘了怎么写的了,出现了报错,所以去查了一些以前的笔记和网上资料,写个博客记录一下:
在这里插入图片描述

 /*未进行lambda的匿名表达式*/
        Set<Apple> apples = new TreeSet<>(new Comparator<Apple>() {
            public int compare(Apple o1, Apple o2) {
                return Double.compare(o2.getPrice(), o1.getPrice());//降序
            }
        });
/*进行lambda之后的表达式未完全版本*/
        Set<Apple> apples1 = new TreeSet<>((Apple o1, Apple o2) -> {
            return Double.compare(o2.getPrice(), o1.getPrice());
        });
/*进行lambda之后的表达式完全版本,也是我出错的地方,
        我对去掉return不理解,去掉花括号就报错,不去掉做不到最简化,因为毕竟就一句话,是可以去掉花括号的*/
        Set<Apple> apples2 = new TreeSet<>((o1, o2) -> Double.compare(o2.getPrice(), o1.getPrice()));
        /* 我疑惑为啥可以去掉return,后来想想他连返回值类型都省略了,return省略也是合情合理
         * 难免让我想到C语言对函数返回值的理解,因为函数结束,无返回值其实是也是有返回值的,
         * 那是给进程看的,提示这个方法体结束了,在看idea对lambda之后的表达式未完全版本是用灰色表示的,说明return没必要
         * 以上是我对lambda省略的理解,*/

一、什么是lambda表达式,为什么要使用?(第一步)


1. 什么是lambda表达式?

Lambda表达式函数式是一个可传递的代码块,可以在以后执行一次或多次。采用支持函数式编程的思想(把函数作为参数传递给另一个函数),对函数式接口(只包含唯一一个抽象方法的接口),通过Lambda表达式来创建该接口的对象。
语法:参数 箭头(->) 表达式
例如:
第一个lambda表达式(代码块为first.length-second.length):

(String first, String second)->first.length()-second.length()

函数式接口:一个:只有一个方法
唯一:只能是抽象方法(接口可以声明Object的非抽象方法让方法不再抽象例如:toString)

2.为什么要使用lambda表达式?(JDK8之后支持)

1.更加简化匿名内部类(一个类在另一个类中定义,创建这个类的对象只是用一次,且没有名字);
2.对使用匿名内部类代码中只保留核心逻辑,看着舒服;
3.当然还有对函数式接口实现的接话,线程的实现的简化等等简化代码量,本篇主要记录和匿名表达式的相关的简化;
4.如果对匿名内部类不是很了解,可以参考一下这篇博客:

https://blog.csdn.net/qq_35394434/article/details/111695348


二、lambda表达式如何做到简化代码的?

1.普通的代码实现功能(无匿名表达式):
public class Test123 {
    public static void main(String[] args) {
        Heihei2 heihei = new Heihei2();
        heihei.function();
    }
}
interface Heihei1 {
    void function();
}
class Heihei2 implements Heihei1 {
    @Override
    public void function() {
   System.out.println("实现功能成功1");
    

2.代码实现功能(使用匿名表达式):

 public static void main(String[] args) {
     Heihei1 heihei = new Heihei1() {
         @Override
         public void function() {
             System.out.println("实现功能成功1");
         }
     };//用分号结束
     heihei.function();
 }
}
interface Heihei1 {
    void function();
}

匿名类是没有类名称的,当然也可以这么写:(类名.方法名)


 public static void main(String[] args) {
    new Heihei1() {
         @Override
         public void function() {
             System.out.println("实现功能成功1");
         }
     }.function();
 }
}
interface Heihei1 {
    void function();
}

其中匿名类为:

new Heihei1() {
         @Override
         public void function() {
             System.out.println("实现功能成功1");
         }
     }

是否使用匿名表达式区别:可以看出匿名类需要在定义时就实例化成对象,简化了通过实现类然后再实例化成对象的过程,代码量更少!


3.1代码实现功能(使用lambda表达式)(三种情况):第一种情况无参数且代码块就一个表达式或多个表达式(表达式内无自由变量的值):以下例子中统一都不含自由变量。

自由变量的值:外围作用域的值,但不能是可变变量,必须是最终变量,因为可变变量容易引发lambda表达式并发执行造成不安全;

                                                                                                                      
public static void main(String[] args) {
/*一个表达式*/
     Heihei1 heihei = ()-> System.out.println("实现功能成功1");
 /*多个表达式
 Heihei1 heihei = ()-> {System.out.println("实现功能成功1");
 System.out.println("实现功能成功1");
 }
*/
     heihei.function();
 }
}
interface Heihei1 {
    void function();
}


是否使用lambda表达式区别:可以看出lambda表达式后的代码在定义和实例化上都进行了简化代码的规则,代码量更少!
该情况语法:

() 箭头(->)一个表达式;//无参()内就啥都不写,但必须保留()

3.2代码实现功能(使用lambda表达式):第二种情况:有一个参数且代码块里一个表达式:

例如:

(String first)->first.length()-1//省略{}
( first)->first.length()-1//省略参数类型和{}
first->first.length()-1//省略参数类型、()和{}

该情况语法:

(参数) 箭头(->)一个表达式;//如果lambda表达式能够推断出参数类型,可以省略写参数

3.3代码实现功能(使用lambda表达式):第三种情况有多个参数且代码块里多个表达式:
/*一个表达式*/
(String first,String second)->{first.length()-second.length();}
( first,second)->first.length()-second.length()//省略参数类型和{}
/*多个表达式*/
(String first,String second)->{first.length()-1;second.length()-1;}
( first, second)->{first.length()-1;second.length()-1;}//省略参数类型

该情况语法:

(参数) 箭头(->){第一个表达式;第二个表达式}//如果lambda表达式能够推断出参数类型,可以省略写参数类型

1.以上就已经算关于匿名表达式的lambda表达式的浅解,然后了解更多,会学习到关于函数接口对lambda表达式的理解,java新增的这个特性好像性就是为解决函数式编程而产生的,
2.就比如:
要使用Arrays.sort();需要传入函数式接口类型的对象,而lambda表达式可以转化为函数式接口(将其看做一个函数,返回一个函数式接口类型的对象)而通过**传统的去先定义接口,再定义实现类,再创建对象才能使用,lambda表达式就显得无比简化了步骤:(和上面的匿名表达式在省略步骤作用很相似)

Arrays.sort(word,(first,second)->first.length()-second.length());

在这里插入图片描述



lambda表达式注意点总结:

1.ambda表达式是不需要指出返回值类型的,它的返回类型总是会由上下文推到得出;(方法体中如果只有一条return语句,那么大括号可以省略,且去掉return),这个是我开始不理解的地方,上网课看视频没有提到的点;
2.ambda表达式怎么简化代码,只需要关注两点:参数个数和方法体内表达式个数:(第一点:参数的只有一个参数,那么小括号可以省略;第二点:方法体当中只有一句代码,大括号可以省略),至于参数类型要不要写,lambda表达式会推断出参数类型,可以不写;

3.匿名内部类多用于实现时间监听器和其他回调,lambda的使用可以说取代了匿名表达式的作用,更加简洁,然而了解了更多发现,lambda表达式的用处不仅仅在于匿名表达式的简化,也有处理线程的实现,函数式接口的运用等等,以后遇到了在进行总结吧,有问题欢迎补充哦!

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值