lambda 表达式学习笔记
在Java中传递一个代码段并不容易,不能直接传递代码段。Java是一个面向对象语言,所以必须构造一个对象,这个对象的类需要一个方法能包含所需的代码。lambda的出现有效的解决这个问题,让代码变得更加简洁。
示例:
class LengthComparator implements Comparator<String>{
public int compare(String first,String second){
return first.length() - second.length();
}
}
...
Arrays.sort(Strings,new LengthComparator());
Arrays.sort(strings,
(String first,String second)-> first.length() - second.length());
lambda表达式,也可称为闭包,是一个可传递的代码块,可以执行一次或多次。
一、lambda表达式的语法:
lambda表达式的语法:参数,箭头(->)以及一个表达式。
(String first,String second)
-> first.length() - second.length();
如无法放在一个表达式中,可放在{}中:
(String first,String second)->
{
if(first.length() < second.length()) return -1;
else if(first.length() > second.length()) return 1;
else return 0;
}
即使lambda表达式没有参数,仍然要提供空括号,就像无参数方法一样:
()-> {for(int i = 100; i >= 0 ; i--) System.out.println(i) ; }
如果方法只有一个参数,而且这个参数的类型可以推导得出,那么甚至可以省略小括号:
ActionListener listener = event ->
System.out.println("The times is" + new Date());
//Instead of (event) -> ... or (ActionEvent event) -> ...
无需指定lambda表达式的返回值类型,lambda表达式的返回值类型总是会由上下文推导得出,例如:
(String first,String second)-> first.length() - second.length();
可以在需要int类型结果的上下文中使用。
示例:
package lambda; import javax.swing.*;
import java.util.Arrays;
import java.util.Date; /**
* Created by kong on 20/11/2017.
*/ public class LambdaTest {
public static void main(String[] args) {
String[] planets = new String[]{"Mercury","Venus","Mars",
"Jupiter","Saturn","Uranus","Neptune"};
System.out.println (Arrays.toString (planets));
System.out.println ("Sorted in dictionary order:");
Arrays.sort (planets);
System.out.println (Arrays.toString (planets));
System.out.println ("Sorted by length:");
Arrays.sort (planets,(first,second) -> first.length () - second.length ());
System.out.println (Arrays.toString (planets)); Timer t = new Timer (1000, event ->
System.out.println ("The time is "+ new Date ()));
t.start();
JOptionPane.showMessageDialog (null,"Quit program?");
System.exit (0);
}
} //运行结果
[Mercury, Venus, Mars, Jupiter, Saturn, Uranus, Neptune]
Sorted in dictionary order:
[Jupiter, Mars, Mercury, Neptune, Saturn, Uranus, Venus]
Sorted by length:
[Mars, Venus, Saturn, Uranus, Jupiter, Mercury, Neptune]
The time is Mon Nov 20 19:58:41 CST 2017
The time is Mon Nov 20 19:58:42 CST 2017
二、函数式接口
对于只有一个抽象方法的接口,需要这种接口的对象时,就可以提供一个lambda表达式。这种接口称为函数式接口(functional interface)。
三、方法的引用
要用 :: 操作符分隔方法名与对象或类名。主要有三种情况:
- object::instanceMethod
- Class::staticMethod
- Class::instanceMethod
在前两种情况中,方法引用等价于提供方法参数的lambda表达式。如:
System.out::println 等价于 x -> System.out.println(x);
Math::pow 等价于(x,y) -> Math.pow(x,y)。
对于第三种情况下,第一个参数会成为方法的目标,如:
String::compareToIgnoreCase 等同于(x,y) -> x.compareToIgnoreCase(y)。
示例:
import java.util.List;
import java.util.ArrayList; public class Java8Tester {
public static void main(String args[]){
List names = new ArrayList(); names.add("Google");
names.add("Runoob");
names.add("Taobao");
names.add("Baidu");
names.add("Sina"); names.forEach(System.out::println);
}
}
四、构造器引用
构造器引用与方法引用类似,只不过方法名为new。如:
ArrayList<String> names = ...;
Stream<Person> stream = names.stream().map(Person::new);
List<Person> people = stream.collect(Collectors.toList());
map方法会为各个列表元素调用Person(String)构造器,如果有多个构造器,编译器会选择有一个String参数的构造器,因为上下文推导出这是在对一个字符串调用构造器。
又如:int[]::new 是一个构造器引用,它有一个参数,即数组的长度。这等价于lambda表达式 x -> new int[x] 。
五、变量作用域
在lambda表达式中捕获的变量必须实际上是最终变量(即这个变量初始之后就不会再为它赋新值);
下面做法是不合法的:
public static void countDowm(int start,int delay){
ActionListener listener = event -> {
start--;//Error:Can't mutate captured variable
System.out.println(start);
};
new Timer(delay,listener).start();
}
在lambda表达式中声明与一个局部变量同名的参数或局部变量是不合法的。如:
Path first = Paths.get("/urs/bin");
Comparator<String> comp =
(first,second) -> first.length() - second.length();
//Error:Variable first already defined
六、处理lambda表达式
使用lambda表达式的重点是延迟执行(deferred execution)。原因如:
- 在一个单独的线程中运行代码;
- 多次运行代码;
- 在算法的适当位置运行代码(如,排序中的比较操作);
- 发生某种情况下执行代码(如,点击了一个按钮,数据到达,等待);
- 只在必要时运行代码;
如重复一个动作n次:
repeat(10,()-> System.out.println("Hello World!"));
lambda 表达式学习笔记的更多相关文章
- C# Lambda表达式学习笔记
本笔记摘抄自:https://www.cnblogs.com/leslies2/archive/2012/03/22/2389318.html,记录一下学习过程以备后续查用. 一.Lambda ...
- java lambda表达式学习笔记
lambda是函数式编程(FP,functional program),在java8中引入,而C#很早之前就有了.在java中lambda表达式是'->',在C#中是‘=>’. 杜甫说:射 ...
- python函数和lambda表达式学习笔记
1. python函数 不同于其他语言,python支持函数返回多个值 为函数提供说明文档:help(函数名)或者函数名.__doc__ def str_max(str1, str2): ''' 比较 ...
- Lambda表达式学习笔记
Lambda基础语法 Java8中引入了一个新的操作符" -> ",该操作符被称为箭头操作符或Lambda操作符,箭头操作符将Lambda表达式拆分成两部分: 左侧:Lamb ...
- C# Lambda 表达式学习之(三):动态构建类似于 c => c.Age == null || c.Age > 18 的表达式
可能你还感兴趣: 1. C# Lambda 表达式学习之(一):得到一个类的字段(Field)或属性(Property)名,强类型得到 2. C# Lambda 表达式学习之(二):LambdaExp ...
- C# Lambda 表达式学习之(四):动态构建类似于 c => c.Age == 2 || c.Age == 5 || c => c.Age == 17 等等一个或多个 OrElse 的表达式
可能你还感兴趣: 1. C# Lambda 表达式学习之(一):得到一个类的字段(Field)或属性(Property)名,强类型得到 2. C# Lambda 表达式学习之(二):LambdaExp ...
- Lamda表达式学习笔记二
Lamda表达式学习笔记二 lamda表达式----方法引用 上一篇讲到Lamda体就是对函数式接口方法的实现 ,在方法体中我们可能会引用其他方法实现逻辑,所以在lamda体中我们可以直接引用器方法 ...
- Lamda表达式学习笔记一
Lamda表达式学习笔记一 一.Lamda语法诠释 三傻大闹宝莱坞的主人公兰彻说的一句话让我映像深刻:用简单的语言来表达同样的意 我并不是说书上的定义怎么怎么不对,而是应该理解书本上的定义,并用简单的 ...
- java 8 中lambda表达式学习
转自 http://blog.csdn.net/renfufei/article/details/24600507 http://www.jdon.com/idea/java/10-example-o ...
随机推荐
- 解决修改完系统默认python版本后yum不可用的问题!!!!!!
文章转自: http://www.linuxidc.com/Linux/2013-05/84727.htm #vi /usr/bin/yum 将文件头部的: #!/usr/bin/python 改为: ...
- mysql分表分库选型
三个方向: 一.应用中自己实现,可直连数据库,自己实现因目前使用的Mybatis框架可以使用两种做法: 1.在SQL中直接分表逻辑,我查了一下代码中的sql,发现join的千姿百态,不大动这些sql这 ...
- [RHEL] 配置 LVM 卷
[RHEL] 配置 LVM 卷 一.Introduction 基础预览 :LVM 认知与扩容操作 高端实战:Linux系统如何迁移至LVM磁盘 之前转过一篇文章 LVM分区在线扩容 ,其原因是我需要给 ...
- leetcode-695-Max Area of Island(BFS)
题目描述: Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land ...
- QuantLib 金融计算——数学工具之优化器
目录 QuantLib 金融计算--数学工具之优化器 概述 Optimizer Constraint OptimizationMethod EndCriteria 示例 Rosenbrock 问题 校 ...
- [原创]php任务调度器 hellogerard/jobby
目录 简介 安装 标准使用 选项 项目实践 简介 一个强大的php层面上的定时任务调度器, 无需修改系统层面的crontab 实际中, php 结合 crontab 来实现定时任务是一种经得住考验的实 ...
- Ubuntu16.04安装视觉SLAM环境(g2o)
1.首先在github上下载g2o图优化库 git clone https://github.com/RainerKuemmerle/g2o.git 2.运行安装以下依赖库 sudo apt-get ...
- 【Three.js】如何选中外部模型
1.问题 three.js中模型选中使用的是射线法,根据摄像机角度,鼠标点击位置和模型选中的distance参数判断来选中模型.对于原生的矢量模型完全没有问题,但是当遇到导入的外部模型,如obj.st ...
- [Xamarin.Android]使用Java Bindings Libary專案 Binding Java元件(.jar) 與Metadata.xml、型別對應 (转帖)
使用Xamarin開發Android APP時, 如果已經有原本就用Java寫好的套件(.jar), 就可以利用Xamarin提供的Java Bindings Libary將他變成C#可使用的元件. ...
- MySQL 备份数据库
一.数据备份 1.备份一个数据库 mysqldump基本语法: mysqldump -u username -p dbname table1 table2 ...-> BackupName.sq ...