博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java Lambda
阅读量:5740 次
发布时间:2019-06-18

本文共 4559 字,大约阅读时间需要 15 分钟。

hot3.png

先来看一个简单的Lambda用法:

//多行注释中为不使用Lambda的写法        /**        Runnable run = new Runnable() {            @Override            public void run() {                System.out.println("Test")            }        };         */	   Runnable run = () -> System.out.println("Test");

我们来看一下Runnable接口:

@FunctionalInterfacepublic interface Runnable {    public abstract void run();}

####我们来看一下Java函数式接口【可以用Lambda方式的接口】的定义: 在Java中,函数式接口是只定义了一个抽象方法的接口。Java 8引入了FunctionalInterface注解来表明一个接口打算成为一个函数式接口。在实际使用中不管FunctionalInterface注解是否存在,Java编译器都会将所有满足该定义的接口看作是函数式接口。 下面我们自己写一个接口看一下能否如Runnable一般:

/** * 拿客 * www.coderknock.com * QQ群:213732117 * 创建时间:2016年07月22日 * 描述: */public interface TestLambdaInterface {    void testInterface();}

我们如下使用该接口,程序能正常编译并输出结果,说明Java编译器都会将所有满足该定义的接口看作是函数式接口

TestLambdaInterface test=()->System.out.println("Test");test.testInterface();

#####接口中定义方法的返回值无关性证明: 当我们将方法的返回值改成String时:

TestLambdaInterface test=()->"test";        test.testInterface();

说明函数式接口与接口中定义方法的返回值无关 下面我们在接口中增加一个方法:

/** * 拿客 * www.coderknock.com * QQ群:213732117 * 创建时间:2016年07月22日 * 描述: */public interface TestLambdaInterface {    void testInterface();	void testInterface2();}

编译时:

D:\Work\LearnJavaFX\src>javac -encoding utf-8 LambdaTest.javaLambdaTest.java:20: 错误: 不兼容的类型: TestLambdaInterface 不是函数接口        TestLambdaInterface test = () -> System.out.println("Test");                                   ^    在 接口 TestLambdaInterface 中找到多个非覆盖抽象方法1 个错误

#####default与static方法的无关性证明: 我们再来看看Java中提供的BinaryOperator接口:

package java.util.function;import java.util.Objects;import java.util.Comparator;@FunctionalInterfacepublic interface BinaryOperator
extends BiFunction
{ public static
BinaryOperator
minBy(Comparator
comparator) { Objects.requireNonNull(comparator); return (a, b) -> comparator.compare(a, b) <= 0 ? a : b; } public static
BinaryOperator
maxBy(Comparator
comparator) { Objects.requireNonNull(comparator); return (a, b) -> comparator.compare(a, b) >= 0 ? a : b; }}

其实现的接口BiFunction:

package java.util.function;import java.util.Objects;@FunctionalInterfacepublic interface BiFunction
{ R apply(T t, U u); default
BiFunction
andThen(Function
after) { Objects.requireNonNull(after); return (T t, U u) -> after.apply(apply(t, u)); }}

该接口可以使用如下方法生成实例:

BinaryOperator
add = (x, y) -> x + y;

说明函数式接口与接口中是否存在default与static方法无关 ####总结 充分说明能成为函数式接口【可以使用Lambda来简化接口操作】的条件为:只定义了一个抽象方法的接口。

Lambda的几种写法

import java.awt.event.ActionListener;import java.util.function.BinaryOperator;/** * 拿客 * www.coderknock.com * QQ群:213732117 * 创建时间:2016年07月22日 * 描述: */        /**         * 对于只有一个抽象方法且返回值为void可以使用下面的方法快捷的生成接口的实例         */        Runnable voidFunc = () -> System.out.println("没有参数的函数式接口");        /**         * 上面的声明其实完整写法应该为:         *  Runnable voidFunc = () -> {System.out.println("没有参数的函数式接口")};         * 对于只有一行语句时,可以省略{},         * 下面是多行语句的情况,{}不能省略         */        Runnable muitiStatement = () -> {            System.out.println("第一行");            System.out.println("第二行");            //多行语句....        };        /**         * 对于有接口中有参数哦的方法我们可以使用         * ActionListener oneParam = (event) -> System.out.println("一个参数");         * 当只有一个参数时,可以省略()如下:         */        ActionListener oneParam = event -> System.out.println("一个参数");        /**         * 多参数就必须将参数放入到()中调用,按照参数顺序写入         */        BinaryOperator
add = (x, y) -> x + y; /** * 上面几种情况中,接口的参数在编译时进行类型的推断,我们亦可以显式声明一下【这样可以避免很多错误】 */ BinaryOperator
add2 = (Long x, Long y) -> x + y;

在Lambda中引用变量需注意的事项

在JDK8对匿名内部类中调用类之外变量必须为final的限制进行了一定的放宽:

String name = "123";        Runnable run = new Runnable() {            @Override            public void run() {              	//在JDK8之前下面的语句是会报错的,只有name是final时才可以使用,但是JDK8中,这样的语句就不会报错                System.out.println(name);            }        };

虽然JDK8中上面的语句时可以的,但这只是减少了我们代码中的编写,编译时还是会将name当做是final所以当有以下几种情况时,编译还是会报错:

//1.对name进行了第二次赋值,这样编译器就会认为name不是final类型		String name = "123";        name="";        Runnable run = () -> {            System.out.println(name);        };		//2.在匿名类方法中对变量进行赋值也是不允许的		String name = "123";          Runnable run = () -> {            name="";            System.out.println(name);        };

如果真的需要在Lambda中或者匿名中对变量赋值,那么应该将其放入数组,或者当做一个类的属性来传递【对象final时可以设置其属性,不能设置其引用】。 ####IDEA中快速生成Lambda语句 输入图片说明

转载于:https://my.oschina.net/coderknock/blog/716246

你可能感兴趣的文章
桌面支持--打不开网页上的pdf附件解决办法(ie-tools-compatibility)
查看>>
nagios监控windows 改了NSclient++默认端口 注意事项
查看>>
干货 | JAVA代码引起的NATIVE野指针问题(上)
查看>>
POI getDataFormat() 格式对照
查看>>
Python 中的进程、线程、协程、同步、异步、回调
查看>>
好的产品原型具有哪些特点?
查看>>
实现java导出文件弹出下载框让用户选择路径
查看>>
刨根问底--技术--jsoup登陆网站
查看>>
OSChina 五一劳动节乱弹 ——女孩子晚上不要出门,发生了这样的事情
查看>>
Spring--通过注解来配置bean
查看>>
pandas 十分钟入门
查看>>
nginx rewrite
查看>>
前端安全系列(一):如何防止XSS攻击?
查看>>
IK分词器安装
查看>>
查看Linux并发连接数
查看>>
你是谁不重要,关键是你跟谁!
查看>>
CSS中规则@media的用法
查看>>
pychecker:分析你的python代码
查看>>
我的友情链接
查看>>
DNS显性+隐性URL转发原理
查看>>