再来看看Java8的新特征——lambda表达式
什么是lambda表达式?
可以把Lambda表达式理解为简洁地表示可传递的匿名函数的一种方式:它没有名称,但它有参数列表、函数主体、返回类型,可能还有一个可以抛出的异常列表。
比如说new一个Thread的传统写法如下
Thread t = new Thread(new Runnable() {
public void run(){
System.out.println("Hello world");
}
});
那么利用lambda表达式的写法就是
Thread t = new Thread(() -> System.out.println("Hello world"));
->
左边的就是参数列表,->
右边的就是函数主体
函数式接口
为什么@FunctionalInterface注解修饰的类只能有一个抽象函数
查看Java8的源码,被@FunctionalInterface修饰的函数叫做函数式接口,例如Predicate
,这些类往往只有一个抽象函数,那是因为“Lambda表达式理解为简洁地表示可传递的匿名函数
”,直接使用的匿名函数的时候没有指定函数名称,所以,如果有两个及以上抽象函数的时候,虚拟机就不知道你要执行哪个方法了,如上例中Runnable的run()方法,我们参数列表部分只使用了(),并没有声明调用的函数名。
JDK自带的函数式接口都在java.util.function路径下,常用的有
public interface Predicate<T>{
boolean test (T t);
}
public interface Consumer<T> {
void accept(T t);
}
public interface Function<T, R> {
R apply(T t);
}
...
函数式接口使用示例
//源码部分
@FunctionalInterface
public interface Predicate<T>{
boolean test(T t);
}
//方法构建
public static <T> List<T> filter(List<T> list, Predicate<T> p) {
List<T> results = new ArrayList<>();
for(T s: list){
if(p.test(s)){
results.add(s);
}
}
return results;
}
//使用示例,通过filter方法,筛选出String不为空的数据
Predicate<String> nonEmptyStringPredicate = (String s) -> !s.isEmpty();
List<String> nonEmpty = filter(listOfStrings, nonEmptyStringPredicate);
其他函数式接口使用示例
为什么lambda表达式使用局部变量必须是final的?
lambda表达式主体部分除了使用参数列表的数据,还可以使用lambda表达式外部的局部变量,但是这些局部变量只能声明一次,否则就会报错。
int portNumber = 1337;
//此时会报错,portNumber必须被final修饰
Runnable r = () -> System.out.println(portNumber);
portNumber = 31337;
因为lambda表达式主体可看作是匿名内部类,访问外部局部变量是需要final的。从线程的角度来说,就是局部变量是一个线程(假设叫线程A),lambda表达式主体是另外一个线程(线程B),当线程A结束的时候,线程B还要访问线程A的数据,肯定是不行的,所以线程B中的变量实质上不是指向线程A中的变量,而是拷贝了一份出来,所以必须保证拷贝出来的数据是不可以改变的。
方法引用
lambda表达式还有一个非常方便的地方,就是方法引用,可以通过类名::方法名
的形式直接使用方法。
例如
//静态方法
Integer::parseInt
//对象的普通方法
String::length
//构造方法
Apple::new
复合lambda表达式的用法
lambda表达式还可以链式调用,同时拥有与或非(negate、and和or)的逻辑判断
//链式调用
inventory.sort(comparing(Apple::getWeight)
.reversed()
.thenComparing(Apple::getCountry));
//非
Predicate<Apple> notRedApple = redApple.negate();
//与
Predicate<Apple> redAndHeavyApple =
redApple.and(a -> a.getWeight() > 150);
//或
Predicate<Apple> redAndHeavyAppleOrGreen =
redApple.and(a -> a.getWeight() > 150)
.or(a -> "green".equals(a.getColor()));
函数复合
Function函数接口提供了两个方法对数据做连续操作
,andThen和compose方法。
Function<Integer, Integer> f = x -> x + 1;
Function<Integer, Integer> g = x -> x * 2;
Function<Integer, Integer> h = f.compose(g);
int result = h.apply(1);
//输出3 ==> )(1*2)+1
andThen方法相当于先执行f函数,再执行g函数。
Function<Integer, Integer> f = x -> x + 1;
Function<Integer, Integer> g = x -> x * 2;
Function<Integer, Integer> h = f.andThen(g);
int result = h.apply(1);
//输出4 ==> (1+1)*2
compose方法相当于先执行g函数,再执行f函数。
接下来
接下来会梳理流的相关知识点、和其他(注入Optionnal、新的时间工具、默认方法等知识)。
再来看看Java8的新特征——lambda表达式的更多相关文章
- Java8新特性-Lambda表达式是什么?
目录 前言 匿名内部类 函数式接口 和 Lambda表达式语法 实现函数式接口并使用Lambda表达式: 所以Lambda表达式是什么? 实战应用 总结 前言 Java8新特性-Lambda表达式,好 ...
- 【Java8新特性】你知道Java8为什么要引入Lambda表达式吗?
写在前面 这是一道真实的面试题,一个读者朋友出去面试,面试官竟然问他这样一个问题:你说说Java8中为什么引入Lambda表达式?引入Lambda表达式后有哪些好处呢?还好这个朋友对Java8早有准备 ...
- 乐字节-Java8新特性-Lambda表达式
上一篇文章我们了解了Java8新特性-接口默认方法,接下来我们聊一聊Java8新特性之Lambda表达式. Lambda表达式(也称为闭包),它允许我们将函数当成参数传递给某个方法,或者把代码本身当作 ...
- Java 8 新特性 - Lambda表达式
Lambda表达式 vs 匿名类既然lambda表达式即将正式取代Java代码中的匿名内部类,那么有必要对二者做一个比较分析.一个关键的不同点就是关键字 this.匿名类的 this 关键字指向匿名类 ...
- C#10新特性-lambda 表达式和方法组的改进
C# 10 中对Lambda的语法和类型进行了多项改进: 1. Lambda自然类型 Lambda 表达式现在有时具有"自然"类型. 这意味着编译器通常可以推断出 lambda 表 ...
- java8新特性——Lambda表达式
上文中简单介绍了一下java8得一些新特性,与优点,也是为本次学习java8新特性制定一个学习的方向,后面几篇会根据上文中得新特性一一展开学习.本文就从java8新特性中比较重要的Lambda表达式开 ...
- java8新特性-lambda表达式和stream API的简单使用
一.为什么使用lambda Lambda 是一个 匿名函数,我们可以把 Lambda表达式理解为是 一段可以传递的代码(将代码像数据一样进行传递).可以写出更简洁.更灵活的代码.作为一种更紧凑的代码风 ...
- Java8新特性 - Lambda表达式 - 基本知识
A lambda expression is an unnamed block of code (or an unnamed function) with a list of formal param ...
- Java8 新特性lambda表达式(一)初始
本篇参考Richard Warburton的 java8 Lambdas :Functional Programming for the Masses 学习lambda表达式之前,需要知道什么是函数式 ...
随机推荐
- mysql 中两个日期相减获得 天 小时 分钟 或者 小时:分钟的格式
/**有一个需求,要求获得两个日期想减的天数,小时数,分钟数.通过查找资料,于是乎我写出了如下代码,来获得两个字段.*/ IFNULL(CONCAT( ,'-',''), ),),'天')), ),) ...
- DevOps专题|基础Agent部署系统
随着京东云业务规模.管理机器规模的扩大,各类agent也在逐渐增多,如日志agent.监控agent.控制系统agent等.这对agent的部署.升级.状态维护提出了很高的要求,一旦某个全局agent ...
- 吴裕雄--天生自然TensorFlow2教程:高阶操作
import tensorflow as tf a = tf.random.normal([3, 3]) a mask = a > 0 mask # 为True元素,即>0的元素的索引 i ...
- Fiddler 自动响应
使用目的:提前设置接口返回规则 便于前端联调 不用每次断点修改数据 操作:
- JavaEE--JNDI(上,简介)
参考:https://blog.csdn.net/yan372397390/article/details/50450332 https://www.landui.com/help/show-6158 ...
- 1-4 无监督学习(Unsupervised Learning)
无监督学习定义: [无监督学习]中没有任何的标签或者是有相同的标签或者就是没标签.所以我们已知数据集,却不知如何处理,也未告知每个数据点是什么.别的都不知道,就是一个数据集.你能从数据中找到某种结构吗 ...
- PAT Advanced 1086 Tree Traversals Again (25) [树的遍历]
题目 An inorder binary tree traversal can be implemented in a non-recursive way with a stack. For exam ...
- this深度面试题2
var name = "windows" var object = { name:"object", show:function(){ return funct ...
- ADS1.2 调试问题
最近一个程序需要用到ADS1.2这个软件,在使用过程中出现了如下问题: 1.由于以前用的是KEIL,所以没找到文件的工程,查资料才发现,这个工程文件打开的文件是MCP格式的文件: 2.调试的时候,没找 ...
- 踩一踩win7安装neo4j的坑
本文使用zip解压方式安装,下载社区版zip 解压到喜欢的文件夹,然后配置环境变量NEO4J_HOME=D:\neo4j-community-3.5.5(自己的解压目录) 配置Path=%NEO4J_ ...