Java--Lambda表达式--使用/教程/实例
原文网址:Java--Lambda表达式--使用/教程/实例_IT利刃出鞘的博客-CSDN博客
简介
说明
本文用示例展示Lambda表达式的用法。同时也会介绍Lambda的相关知识。
Lambda表达式介绍
- Lambda表达式的本质只是一个"语法糖",由编译器推断并帮你转换包装为常规的代码,因此你可以使用更少的代码来实现同样的功能。
- Lambda表达式是Java SE 8中一个重要的新特性。
Lambda与匿名内部类
Lamda表达式指的是应用在SAM(SingleAbstractMethod,含有一个抽象方法的接口)环境下的一种简化定义形式。
Lambda比匿名内部类的优点
- 简洁(详见下边“函数式接口”)
Lamda相对于匿名内部类的缺点
- Lamda对应的接口只能有一个方法。
- 匿名内部类对应的接口可以有多个方法
对接口的要求
1.Lambda 规定接口中只能有一个需要被实现的方法(即抽象方法)。
在一个接口中,后边几个可同时存在:一个抽象方法(只能有一个)、多个default方法、多个static方法。
// jdk 8 中有另一个新特性:default, 被 default 修饰的方法会有默认实现,不是必须被实现的方法,所以不影响 Lambda 表达式的使用。
2.@FunctionalInterface:用来修饰函数式接口。
@FunctionalInterface写不写都可以。此注解主要用于编译级错误检查:当接口不符合函数式接口定义的时候,编译器会报错。
正确例子,没有报错:
@FunctionalInterface
public interface HelloWorldService {void sayHello(String msg);
}
错误例子,报错:
接口中包含了两个抽象方法,违反了函数式接口的定义,提示在接口中找到多个非重写的抽象方法。
注意: 加不加 @FunctionalInterface对于接口是不是函数式接口没有影响,该注解只是提醒编译器去检查该接口是否仅包含一个抽象方法。
变量和作用域
- Lambda 表达式只能引用标记了 final 的外层局部变量。即不能在 lambda 内部修改定义在域外的局部变量,否则编译报错
- Lambda 表达式的局部变量可以不用声明为 final,但是必须不可被后面的代码修改(即隐性的具有 final 的语义)
- Lambda 表达式中不允许声明一个与局部变量同名的参数或者局部变量。
格式
lambda表达式的重要特征
- 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
- 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
- 可选的大括号:若主体包含了一个语句,就不需要使用大括号。例: () -> Sysout.out.println("Test");
- 可选的返回关键字:若主体只有一个表达式返回值则编译器会自动返回值,大括号需指定明表达式返回了一个数值。
Lambda 表达式的简单例子
// 1. 不需要参数,返回值为 5
() -> 5
// 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x
// 3. 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y
// 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)
语法格式
格式:
(parameters) -> statement 或(parameters) ->{ statements; }
左侧:Lambda 表达式的参数列表
右侧:Lambda 表达式中所需要执行的功能 (Lambda体)
语法格式一:无参数,无返回值
() -> Sysout.out.println("Test");
语法格式二:有一个参数,并且无返回值
(X)-> Sysout.out.println(x);
语法格式三:如果有一个参数括号可以不写
X-> Sysout.out.println(x);
语法格式四:有两个以上的参数,有返回值,并且Lambda体中有多条语句,语法体中需要用{}
Comparator<Integer> comparator = (o1, o2) -> {
System.out.println("Test");
return Integer.compare(o1, o2);
};
语法格式五:Lambda体中只用一条语句,return和{}可以省略不写
Comparator<Integer> comparator = (o1, o2)->Integer.compare(o1, o2);
语法格式六:表达式的参数列表的数据类型可以省略不写,JVM编译器通过上下文推断出数据类型
(x ,y ) ->Integer.compare(x ,y)
实例
其他网址
Java8学习笔记(一)--Lambda表达式 - 舒山 - 博客园
Java中Lambda表达式的使用 - Franson - 博客园
函数式接口
无参数无返回值
package org.example.a;@FunctionalInterface
interface Interface {void run();
}public class Demo{public static void main(String[] args) {Interface params = new Interface() {@Overridepublic void run() {System.out.println("Anonymous Internal Class: ");}};Interface params1 = () -> System.out.println("Lambda: ");params.run();params1.run();}
}
执行结果
Anonymous Internal Class:
Lambda:
有参数无返回值
package org.example.a;@FunctionalInterface
interface Interface {void run(String s);
}public class Demo{public static void main(String[] args) {Interface params = new Interface() {@Overridepublic void run(String s) {System.out.println("Anonymous Internal Class: " + s);}};Interface params1 = (s) -> System.out.println("Lambda: " + s);params.run("hello");params1.run("hi");}
}
执行结果
Anonymous Internal Class: hello
Lambda: hi
有参数有返回值
package org.example.a;@FunctionalInterface
interface Interface {String run(String s);
}public class Demo{public static void main(String[] args) {Interface params = new Interface() {@Overridepublic String run(String s) {System.out.println("Anonymous Internal Class: " + s);return "abc";}};Interface params1 = (s) -> {System.out.println("Lambda: " + s);return "def";};System.out.println(params.run("hello"));System.out.println(params1.run("hi"));}
}
执行结果
Anonymous Internal Class: hello
abc
Lambda: hi
def
lambda作为参数
传递一个函数
package org.example.a;interface IRun {String welcome(String string);
}class Util {public static long executionTime1(IRun iRun, String string) {long startTime = System.currentTimeMillis();System.out.println(iRun.welcome(string));//本处刻意添加这一无意义延时,防止执行太快返回0try {Thread.sleep(10);} catch (Exception e) {System.out.println(e);}long endTime = System.currentTimeMillis();return endTime - startTime;}public long executionTime2(IRun iRun, String string) {long startTime = System.currentTimeMillis();System.out.println(iRun.welcome(string));//本处刻意添加这一无意义延时,防止执行太快返回0try {Thread.sleep(10);} catch (Exception e) {System.out.println(e);}long endTime = System.currentTimeMillis();return endTime - startTime;}public static String hello(String string){String tmp;tmp = "hello: " + string;return tmp;}public String hi(String string){String tmp;tmp = "hi: " + string;return tmp;}
}public class Demo {public static void main(String[] args) {long time1 = Util.executionTime1(Util::hello, "Tony");long time2 = new Util().executionTime2(new Util()::hi, "Pepper");System.out.println("time1: " + time1 + "ms");System.out.println("time2: " + time2 + "ms");}
}
执行结果
hello: Tony
hi: Pepper
time1: 11ms
time2: 11ms
直接传递lambda函数
package org.example.a;interface IRun {String welcome(String string);
}class Util {public static long executionTime(IRun iRun, String string) {long startTime = System.currentTimeMillis();System.out.println(iRun.welcome(string));//本处刻意添加这一无意义延时,防止执行太快返回0try {Thread.sleep(10);} catch (Exception e) {System.out.println(e);}long endTime = System.currentTimeMillis();return endTime - startTime;}
}public class Demo {public static void main(String[] args) {long time = Util.executionTime((string -> {String tmp;tmp = "hello: " + string;return tmp;}), "Tony");System.out.println("time: " + time + "ms");}
}
执行结果
hello: Tony
time: 11ms
遍历集合
package org.example.a;import java.util.ArrayList;
import java.util.List;public class Demo{public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("aaa");list.add("bbb");//以前的循环方式for (String string : list) {System.out.println(string);}//使用lambda表达式输出list中的每个值list.forEach(c->{System.out.println(c);});// 在 Java 8 中使用双冒号操作符(double colon operator)。也属于lamda表达式list.forEach(System.out::println);}
}
执行结果
aaa
bbb
aaa
bbb
aaa
bbb
创建线程
package org.example.a;public class Demo{public static void main(String[] args) {new Thread(new Runnable() {@Overridepublic void run() {System.out.println("Anonymous Internal Class !");}}).start();new Thread(() -> System.out.println("Lambda !")).start();}
}
执行结果
Anonymous Internal Class !
Lambda !
排序
package org.example.a;import java.util.Arrays;
import java.util.Comparator;public class Demo{public static void main(String[] args) {String[] players = {"Rafael Nadal", "Novak Djokovic", "Stanislas Wawrinka"};Arrays.sort(players, new Comparator<String>() {@Overridepublic int compare(String o1, String o2) {return (o1.compareTo(o2));}});// Comparator<String> sortByName = (String s1, String s2) -> (s1.compareTo(s2));
// Arrays.sort(players, sortByName);// Arrays.sort(players, (String s1, String s2) -> (s1.compareTo(s2)));for(String string:players){System.out.println(string);}}
}
执行结果(换成注释掉的两种任意一种都是一样的)
Novak Djokovic
Rafael Nadal
Stanislas Wawrinka
其他网址
Java中Lambda表达式的使用 - Franson - 博客园
另见:《JAVA开发实战经典 第2版》=> 16.8 Lamda表达式
Java--Lambda表达式--使用/教程/实例相关推荐
- 【外文翻译】外国友人写得很不错的Java Lambda表达式入门教程,我终于翻译好给大家啦!!!...
" 英语原文的链接在最底下的"阅读原文" " 简介 (译者认为: 超过 3 行的逻辑就不适用 Lambda 表达式了.虽然看着很先进,其实 Lambda 表达式 ...
- java拉姆达表达式事例,Java Lambda表达式详解和实例
简介 Lambda表达式是Java SE 8中一个重要的新特性.lambda表达式允许你通过表达式来代替功能接口. lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体( ...
- Java Lambda 表达式(又名闭包 (Closure)/ 匿名函数 ) 笔记
Java Lambda 表达式(又名闭包 (Closure)/ 匿名函数 ) 笔记 根据 JSR 335, Java 终于在 Java 8 中引入了 Lambda 表达式.也称之为闭包或者匿名函数. ...
- Lambda表达式的生动理解以及Java Lambda表达式常见使用场景
本篇承接上一篇 Java Lambda 表达式快速学习 , 对Lambda 表达式的语法格式进行演化说明, 并对Java 中Lambda表达式的常见使用场景进行说明. Lambda 表达式怎么来的? ...
- Java Lambda 表达式快速学习
Lambda 表达式来源于数学, 因为其简洁性,很多开发语言都支持, Java 在版本8 开始引入. Lamba 表达式是什么? 匿名内部类 接口只能有一个需要被实现的方法 Lamba 表达式作用 代 ...
- java lambda表达式学习笔记
lambda是函数式编程(FP,functional program),在java8中引入,而C#很早之前就有了.在java中lambda表达式是'->',在C#中是'=>'. 杜甫说:射 ...
- java lam表达式_详细分析Java Lambda表达式
在了解Lambda表达式之前我们先来区分一下面向对象的思想和函数式编程思想的区别 面向对象的思想: 做一件事情,找一个能解决这个事情的对象,调用他的方法来解决 函数时编程思想: 只要能获取到结果,谁去 ...
- 深入理解Java Lambda表达式,匿名函数,闭包
前言 对于Lambda表达式一直是知其然不知其所以然,为了搞清楚什么是Lambda表达式,以及Lambda表达式的用法和作用,本文应运而生当做学习笔记分享出来,欢迎指正交流. 什么是Lambda 让我 ...
- Java Lambda表达式入门
本文转自:http://blog.csdn.net/renfufei... 转载请注明出处 原文链接: Start Using Java Lambda Expressions 下载示例程序 Examp ...
最新文章
- 仅靠合成数据就能实现真实人脸分析!微软这项新研究告别人工标注
- .Net 中 获取当前应用程序启动目录的几个方法和Path.Combine 细节
- Scan Chain的原理与实现(实践) - Compression Flow
- [TCP/IP] ping traceroute和TTL
- 用 subsetting 限制连接池中的连接数量
- php实例化类的方法,在PHP中实例化类实例的不同方法
- Python 持久存储
- Java随机生成名字大全 手机号
- Matlab与线性代数 -- Hilbert矩阵
- tomcat 是什么
- 电脑变慢,电脑突然变慢怎么办 电脑卡死原因和解决方法
- MySQL查年龄18到22的信息_Mysql查询SQL相关总结(根据生日以及身份证查询年龄以及性别区域等)...
- java身份证号码验证
- USB PD快充协议详解(待续)
- 三维气象数据可视化系统介绍
- Line APP端协议登录、群发、拉群功能
- 计算机刷新的作用,为什么要刷新 刷新有什么用?
- Lyft公开“业内最大”数据集, 自动驾驶战场加速安卓化?
- 配置Log4j(很详细)
- 网站设计全攻略-3、确定网站的栏目和版块
热门文章
- Linux 使用wegt报错,ERROR: cannot verify mirrors.tuna.tsinghua.edu.cn‘s certificate, issue
- 【常见Web应用安全问题】---4、Directory traversal
- 研究生入学一个月的感想
- 男士化妆品行业调研报告 - 市场现状分析与发展前景预测
- Web-python+selenium-自动化测试技术-考试系统测试脚本
- TPS22930AYZVR
- 六 面向对象高级属性
- MDBT+SM36设置多工厂按顺序执行物料需求计划
- 程序员电脑桌面是什么样的? 网友: IE浏览器必删, 不能留! 1
- Slumdog Millionaire is destiny