自己理解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();
    }

}

总结

1.一个代码块被赋值给了一个变量。

1.lambda表达式本身就是某个接口的实现。

原文地址:https://www.cnblogs.com/yanlong300/p/8890822.html

时间: 2024-10-09 23:25:55

自己理解Java中的lambda的相关文章

理解java中的volatile关键字

Java语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量.这两种机制的提出都是为了 实现代码线程的安全性.Java 语言中的 volatile 变量可以被看作是一种 "程度较轻的 synchronized":与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少,但是它所能实现的功能也仅是 synchronized 的一部分. volatile 写和读的内存语义: 线程 A 写一个 volatile 变量,实质上是线程 A

深刻理解Java中形参与实参,引用与对象的关系

声明:本博客为原创博客,未经允许,不得转载!原文链接为http://blog.csdn.net/bettarwang/article/details/30989755 我们都知道,在Java中,除了基本数据类型之外,其他的都是引用类型,当它们作为函数参数时,传递的也是引用,通过引用可以改变对象的值,很多人便因此而忽略形参与实参,引用与对象的关系问题.废话不多说,先看下面一个例子: import java.util.*; public class Student { private String

深入理解Java中的IO

深入理解Java中的IO 引言:     对程序语言的设计者来说,创建一个好的输入/输出(I/O)系统是一项艰难的任务 < Thinking in Java >   本文的目录视图如下: Java IO概要 a.Java IO中常用的类 b.Java流类的类结构图 1.流的概念和作用 2.Java IO所采用的模型  : 3.IO流的分类 4.Java IO流对象 1.输入字节流InputStream 2.输出字节流OutputStream 3.字符输入流Reader 4.字符输出流Write

深刻理解Java中final的作用(一):从final的作用剖析String被设计成不可变类的深层原因

声明:本博客为原创博客,未经同意,不得转载!小伙伴们假设是在别的地方看到的话,建议还是来csdn上看吧(原文链接为http://blog.csdn.net/bettarwang/article/details/26744661),看代码和提问.讨论都更方便. Java中final的作用主要表如今三方面:修饰变量.修饰方法和修饰类.以下就从这两个方面来解说final的作用.在文末从final及类的设计安全性出发,论述了Java中String为何要被设计成不可变类. 1.final修饰变量 fina

线程的生命周期 - 理解Java中线程的状态

刚刚开始学cocos2-x,仅仅是按照教程把已经安了一般Android的开发环境的eclipse重新升级到安装好cdt和ndk就花了我几十小时,差点都要放弃了. 参考博客 D:\cocos2d-x\cocos2d-x-2.2.3\cocos2dx\platform\third_party\android\prebuilt 说说大概的过程: 下载ndk插件,ndk包,cdt插件.最开始我按照书上的下载了cocos2d-x 2.0.1,希望跟书上统一起来,这样以后学习的时候可以参考书上的也不会遇到太

理解Java中的弱引用(Weak Reference)

理解Java中的弱引用(Weak Reference) 本篇文章尝试从What.Why.How这三个角度来探索Java中的弱引用,理解Java中弱引用的定义.基本使用场景和使用方法.由于个人水平有限,叙述中难免存在不准确或是不清晰的地方,希望大家可以指出,谢谢大家:) 1. What——什么是弱引用? Java中的弱引用具体指的是java.lang.ref.WeakReference<T>类,我们首先来看一下官方文档对它做的说明: 弱引用对象的存在不会阻止它所指向的对象变被垃圾回收器回收.弱引

深入理解 Java中的 流 (Stream)

首先,流是什么? 流是个抽象的概念,是对输入输出设备的抽象,Java程序中,对于数据的输入/输出操作都是以"流"的方式进行.设备可以是文件,网络,内存等. 流具有方向性,至于是输入流还是输出流则是一个相对的概念,一般以程序为参考,如果数据的流向是程序至设备,我们成为输出流,反之我们称为输入流. 可以将流想象成一个"水流管道",水流就在这管道中形成了,自然就出现了方向的概念. 当程序需要从某个数据源读入数据的时候,就会开启一个输入流,数据源可以是文件.内存或网络等等.

深刻理解Java中的String、StringBuffer和StringBuilder的区别

首先简单地来梳理一下Java中String.StringBuffer和StringBuilder各自的含义. 1.String类 首先,它是线程安全的,即可以用于多线程编程中: 其次,String类的对象是不可变的,即在定义时就确定了,类似String str="Hello";str+="Java";的语句其实是生成了新的对象,只是我们未察觉到而已.但是注意在大量的字符串新建对象时消耗就很可观,这时必须考虑采用StringBuffer或StringBuilder,否

JDK学习---深入理解java中的LinkedList

本文参考资料: 1.<大话数据结构> 2.http://blog.csdn.net/jzhf2012/article/details/8540543 3.http://blog.csdn.net/jzhf2012/article/details/8540410 4.http://www.cnblogs.com/ITtangtang/p/3948610.html 5.http://blog.csdn.net/zw0283/article/details/51132161 本来在分析完HashSe