自己理解Java中的lambda
lambda是什么
“Lambda 表达式”(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包(注意和数学传统意义上的不同)。
将一个变量传入一个匿名函数然后对传入函数进行操作。由于java中并没有脱离类而存在的函数,所以通常独立函数是以一个匿名内部类+一个方法构成的。lambda表达式代替的函数既没有方法名也没有访问修饰符、明确的返回类型声明。
实现解析
下面将解析下lambda与java的逻辑。
函数式变换最大的特点是:将一个函数(方法)赋值给一个变量。
函数式编程环境中比如javaScript
var fun = function(){
...
}
那么在Java中大概是这个样子的。
var doSomthing = public void doSomthing(){
...
}
这个public 关键字是多余的,代码就变成了这个样子。
var doSomthing = void doSomthing(){
...
}
这个返回值类型可以依据内部return类型推导,所以返回值类型也不须要的。
var doSomthing = doSomthing(){
...
}
方法名在之前已经定义过了,代码就变成了这个样子。
var doSomthing = (){
...
}
由于这样看起来怪怪的。所以使用->来定义方法参数和主体。()表示方法的参数列表,{}内部表示方法体。单行方法体可以省略{},强烈不建议这么做。
var doSomthing = ()->{
...
}
这就相当于一个代码块被赋值给了一个变量,这就是一个lambda表达式。
var这个关键字1.8版本的java中是没有的。那么这个变量是什么呢。
在java1.8中所有的 lambda表达式本身就是某个接口的实现,所以var应该是某个接口。
下面定义一个接口
public interface MethodInterface {
void doSomething();
}
一个接口函数需要被实现的接口类型,我们叫它”函数式接口“。为了避免后来的人在这个接口中增加接口函数导致其有多个接口函数需要被实现,变成"非函数接口”,我们可以在这个上面加上一个声明@FunctionalInterface, 这样别人就无法在里面添加新的接口函数了。
@FunctionalInterface
public interface MethodInterface {
void doSomething();
}
函数式接口通常只有一个方法。
我们就可以直接把Lambda作为参数传给函数, 而传统的Java必须有明确的接口实现的定义。
那么上面的函数就成了
MethodInterface methodInterface = ()->{
...
}
那么我们将如何使用它呢.
methodInterface.doSomthing();
这么调用即可。
这个接口通用性很强并且定义起来太麻烦,我们是不是有其他办法替换掉MethodInterface这个接口。
有的,在jdk1.8的java.util.function包中包含了大量定义好的接口。
| 接口名 | 参数 | 返回值 |
|---|---|---|
| Consumer<T> | T | void |
| BiConsumer<T, U> | T,U | void |
| BiConsumer<T, U, R> | T,U | R |
| BooleanSupplier | 无 | Boolean |
| DoubleBinaryOperator | Double,Double | Double |
以上列举并不完全。
当然可以向上述文章那样自定义接口方法类型但是需要@FunctionalInterface注解
实战代码
创建线程接口方式
接口
package java.lang;
@FunctionalInterface
public interface Runnable {
void run();
}
public class LambdaTest {
private static final int TOTAL = 5000;
private static AtomicInteger i = new AtomicInteger(0);
public static void main(String[] args) throws InterruptedException {
Executor executor = Executors.newCachedThreadPool();
CountDownLatch countDownLatch = new CountDownLatch(TOTAL);
for(int j=0;j<TOTAL;j++){
executor.execute(()->{
add();
countDownLatch.countDown();
});
}
countDownLatch.await();
System.out.println("求和的结果为:"+i);
}
private static void add(){
i.incrementAndGet();
}
}
总结
- 一个代码块被赋值给了一个变量。
- lambda表达式本身就是某个接口的实现。
自己理解Java中的lambda的更多相关文章
- 理解和运用Java中的Lambda
前提 回想一下,JDK8是2014年发布正式版的,到现在为(2020-02-08)止已经过去了5年多.JDK8引入的两个比较强大的新特性是Lambda表达式(下文的Lambda特指JDK提供的Lamb ...
- Lambda 表达式,Java中应用Lambda 表达式
一.Lambda 表达式 简单来说,编程中提到的 lambda 表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数. 链接:知乎 先举一个普通的 Python 例 ...
- 理解Java中的弱引用(Weak Reference)
本篇文章尝试从What.Why.How这三个角度来探索Java中的弱引用,理解Java中弱引用的定义.基本使用场景和使用方法.由于个人水平有限,叙述中难免存在不准确或是不清晰的地方,希望大家可以指出, ...
- 深刻理解Java中final的作用(一):从final的作用剖析String被设计成不可变类的深层原因
声明:本博客为原创博客,未经同意,不得转载!小伙伴们假设是在别的地方看到的话,建议还是来csdn上看吧(原文链接为http://blog.csdn.net/bettarwang/article/det ...
- [译]线程生命周期-理解Java中的线程状态
线程生命周期-理解Java中的线程状态 在多线程编程环境下,理解线程生命周期和线程状态非常重要. 在上一篇教程中,我们已经学习了如何创建java线程:实现Runnable接口或者成为Thread的子类 ...
- 深入理解Java中的不可变对象
深入理解Java中的不可变对象 不可变对象想必大部分朋友都不陌生,大家在平时写代码的过程中100%会使用到不可变对象,比如最常见的String对象.包装器对象等,那么到底为何Java语言要这么设计,真 ...
- 深入理解Java中的IO
深入理解Java中的IO 引言: 对程序语言的设计者来说,创建一个好的输入/输出(I/O)系统是一项艰难的任务 < Thinking in Java > 本文的目录视图如下: ...
- 理解Java中的ThreadLocal
提到ThreadLocal,有些Android或者Java程序员可能有所陌生,可能会提出种种问题,它是做什么的,是不是和线程有关,怎么使用呢?等等问题,本文将总结一下我对ThreadLocal的理解和 ...
- 深入理解Java中配置环境变量
深入理解Java中配置环境变量 配置的目的: 本来只在安装JDK的bin目下能运行java.exe,javac.exe,jar.exe,javadoc.exe等Java开发工具包命令,我们现在想让在所 ...
随机推荐
- java 中自定义类的概述
作业: 描述商品类 Goods 4个属性 商品名字 大小 价格 库存 把商品类放进集合中 小米品牌 大小 价格 库存的数量 都存集合 华为..... 魅族 public class Goods{ St ...
- kubernetes控制器之DaemonSet
转载于https://blog.csdn.net/bbwangj/article/details/82867472 什么是 DaemonSet? DaemonSet 确保全部(或者一些)Node 上运 ...
- jQuery EasyUI Datagrid性能优化专题
jQuery EasyUI的Datagrid组件功能算是很强大了,不过性能确实不怎么乐观,而对于性能问题,网络上几乎也找不到相关的优化资料,所谓的牛人们可能都望而却步了.本博客以后会带着分析Data ...
- 单例设计模式Singleton之懒加载模式(懒汉模式)【原】
单例设计模式Singleton之懒加载模式(懒汉模式) SingletonLazy.java类 package kingtool; import kingtool.http.IPTool; publi ...
- xml/map转换器,递归设计思路【纯原】
xml/map转换器 xml转换: xml/map转换器 xml合并: xml合并 snagit图片:http://pan.baidu.com/s/1nuKJD13 git样例: https://gi ...
- 如何使用less(变量,混合,匹配,运算,嵌套...)
如何使用less及一些常用的(变量,混合,匹配,运算,嵌套...) less的介绍及编译工具 什么是less 1.LESSCSS是一种动态样式语言,属于CSS预处理语言的一种,它使用类似CSS的语法, ...
- 19. SpringBoot_web开发-使用外部Servlet容器&JSP支持
還沒有web.xml,生 配置tomcat 嵌入式Servlet容器:应用打成可执行的jar 优点:简单.便携: 缺点:默认不支持JSP.优化定制比较复杂 使用定制器[ServerPropertie ...
- 1.springboot:入门程序
一.Spring Boot 简介 官网英文: Spring Boot makes it easy to create stand-alone, production-grade Spring base ...
- MongoDB - 日常操作二
MongoDB 开启认证与用户管理 ./mongo # 先登录 use admin # 切换到admin库 db.addUser(") # 创建用户 db.addUser('zhansan ...
- R 的农场 chebnear (二分答案+最近平面点对)
题面 \(solution:\) 这道题想到二分答案应该是不难的,因为题目是求平均工资的最小值,这个显然具备单调性: 我们设平均工资的最小值为ans,如果我们现在的平均工资x小于ans那么将x带入题目 ...