当前位置: 首页 > news >正文

Java 8 Lambda表达式,让你的代码更简洁

Lambda表达式是Java 8一个非常重要的新特性。它像方法一样,利用很简单的语法来定义参数列表和方法体。目前Lambda表达式已经成为高级编程语言的标配,像Python,Swift等都已经支持Lambda表达式。

在Java 8的实现中,Lambda表达式其本质只是一个“语法糖”,经过编译器推断和处理,将其转换包装为常规的Java代码,因此就像题目所写的那样,可以让你的代码更为简洁。

Lambda表达式的基本语法:(parameters) -> expression 或 (parameters) -> { statements; }

Lambda表达式并不是一个方法,它可以用来定义了一个代码块,形式上很像是Java的匿名内部类。Lambda表达式通常会赋值给一个函数式接口,函数式接口是指只有一个抽象方法的接口。Lambda表达式可以通过上下文环境来推断变量类型, 因此在使用时尽量不人为明确的指定变量类型。

举例来看,假设我们有一个List<String>类型的列表list,如果要遍历并打印列表内容,Java 7以前的代码如下:

1 for (String s : list) {
2     System.out.println(s);
3 }

 

Java 8来实现的话:

1 list.forEach((s) -> System.out.println(s));

或者

1 list.forEach(System.out::println);

再看一个例子,假设我们要对list进行排序,Java 7的代码如下:

1 Collections.sort(list, new Comparator<String>() {
2     @Override
3     public int compare(String p1, String p2) {
4         return p1.compareTo(p2);
5     }
6 });

Java 8来实现的话:

1 Collections.sort(list, (String p1, String p2) -> p1.compareTo(p2));

需要注意的是,Lambda表达式可以做参数类型推断,这里我们可以充分利用这一点,p1和p2参数前面的String是不需要的,因此可以简化一步如下:

1 Collections.sort(list, (p1,p2) -> p1.compareTo(p2));

更进一步:

1 list.sort((p1,p2) -> p1.compareTo(p2));

是不是简洁了很多:)

Lambda表达式也可以用来代替匿名类。例如我们要实现Runnable接口,Java 7的代码如下:

1 new Thread(new Runnable() {
2     @Override
3     public void run() {
4         System.out.println("Hello world !");
5     }
6 }).start();

 

Java 8来实现的话:

1 new Thread(() -> System.out.println("Hello world !")).start();

用Lambda表达式来实现Runnable,将五行代码转换成一行语句。

合理使用Lambda表达式,不仅能简化几行代码,还能做到合理的代码抽象。当我们在实现的两个很大的方法时,如果大部分的代码都是相同的,只有一小点代码不一样时,我们可以通过将Lambda表达式作为参数传入,以达到不同表意的目的。

前面提到的函数式接口(Functional Interfaces),它表示只有一个抽象方法的接口,可以用来指向Lambda表达式。例如:

1 Consumer c = (s) -> System.out.println(s);

Java 8在java.util.function包中实现了新的几个:

  • Function<T, R>:接受一个参数T,返回结果R

  • Predicate<T>:接受一个参数T,返回boolean

  • Supplier<T>:不接受任何参数,返回结果T

  • Consumer<T>:接受一个参数T,不返回结果

  • UnaryOperator<T>:继承自Function<T, T>,接受一个参数T,返回相同类型T的结果

  • BiFunction<T, U, R>:接受两个参数T和U,返回结果R

  • BinaryOperator<T>:继承自BiFunction<T, T, T>,接受两个相同类型T的参数,返回相同类型T的结果

  • ……

另外,我们最为熟悉的函数式接口还有:

  • Runnable:实际上是不接受任何参数,也不返回结果

  • Comparable<T>:实际上是接受两个相同类型T的参数,返回int

  • Callable<V>:不接受任何参数,返回结果V

通常我们应该尽量使用标准的函数式接口,如果我们要自定义的话,可以使用@FunctionalInterface注解,例如:

1 @FunctionalInterface
2 public interface funcInterface {
3     public abstract B op(A a);
4 }

 

在将函数式接口作为参数时,需要注意尽量避免方法重载。由于Lambda表达式根据所在环境的目标类型来决定Lambda表达式的类型(也就是Target Typing), 因此方法重载有时会导致编译器犯晕。我们可以使用不同的方法名来解决这个问题。

在这里,我们还需要澄清几点:

  • Lambda表达式并不是函数式接口。它能赋值给函数式接口,是因为编译器将它包装成了对应的函数式接口;

  • 更进一步,Lambda表达式也不是匿名类:

    • 它并没有定义新的作用域,外面定义的局部变量在Lambda表达式内部是可见的;

    • 它不能改变外部变量的值,只能读取final或者effectively final的变量;

    • 它不能前向读取外部变量,也就是只有在外部变量申明之后才能读取,而在匿名内部类是可以的;

Java 8 还增强了对集合数据的批量操作Stream,通常会和Lambda表达式一起使用。Lambda表达式和 Stream 可以说是Java语言从添加泛型(Generics)和注解(annotation)以来最大的变化了。下一篇文章将重点介绍Stream。

转载于:https://www.cnblogs.com/pkufork/p/java_8_lambda.html

相关文章:

  • 使用scrapy创建工程
  • 文件属性
  • 插入排序
  • python核心编程第六章练习--6.5.d
  • python 迭代器和生成器
  • java---构造器
  • PAT甲题题解-1096. Consecutive Factors(20)-(枚举)
  • 汇编、c语言、c++的一些想法。
  • cocos2dx-lua_修改源码流程(cocos2dx-3.10、win7、Cocos Code IDE1.2)
  • HTML5全屏(Fullscreen)API详细介绍
  • 如何解决流程开发中SheetRadioButtonList页面取值问题
  • Unable to find vcvarsall.bat的解决办法
  • QQ表情的发送与接收
  • mysql用户授权
  • Vim使用
  • JS变量作用域
  • Laravel深入学习6 - 应用体系结构:解耦事件处理器
  • LeetCode18.四数之和 JavaScript
  • Nodejs和JavaWeb协助开发
  • RxJS 实现摩斯密码(Morse) 【内附脑图】
  • SwizzleMethod 黑魔法
  • Vue2 SSR 的优化之旅
  • 首页查询功能的一次实现过程
  • 腾讯大梁:DevOps最后一棒,有效构建海量运营的持续反馈能力
  • 网页视频流m3u8/ts视频下载
  • 协程
  • 一个项目push到多个远程Git仓库
  • 在weex里面使用chart图表
  • gunicorn工作原理
  • kubernetes资源对象--ingress
  • ###51单片机学习(1)-----单片机烧录软件的使用,以及如何建立一个工程项目
  • #常见电池型号介绍 常见电池尺寸是多少【详解】
  • (003)SlickEdit Unity的补全
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (一)SpringBoot3---尚硅谷总结
  • (原創) 博客園正式支援VHDL語法著色功能 (SOC) (VHDL)
  • .jks文件(JAVA KeyStore)
  • .net core webapi Startup 注入ConfigurePrimaryHttpMessageHandler
  • .NET I/O 学习笔记:对文件和目录进行解压缩操作
  • .NET MVC、 WebAPI、 WebService【ws】、NVVM、WCF、Remoting
  • .NET MVC第三章、三种传值方式
  • .Net 垃圾回收机制原理(二)
  • .NET 中选择合适的文件打开模式(CreateNew, Create, Open, OpenOrCreate, Truncate, Append)
  • .NET业务框架的构建
  • @Autowired和@Resource装配
  • @manytomany 保存后数据被删除_[Windows] 数据恢复软件RStudio v8.14.179675 便携特别版...
  • @Transactional 详解
  • [ CTF ] WriteUp- 2022年第三届“网鼎杯”网络安全大赛(朱雀组)
  • [<事务专题>]
  • [C#]使用PaddleInference图片旋转四种角度检测
  • [C++基础]-初识模板
  • [CF482B]Interesting Array
  • [FC][常见Mapper IRQ研究]
  • [Firefly-Linux] RK3568修改控制台DEBUG为普通串口UART
  • [hdu 2896] 病毒侵袭 [ac自动机][病毒特征码匹配]