再来看看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表达式之前,需要知道什么是函数式 ...
随机推荐
- Idea 中的快捷键(mac)
Mac键盘符号和修饰键说明 ⌘ Command ⇧ Shift ⌥ Option ⌃ Control ↩︎ Return/Enter ⌫ Delete ⌦ 向前删除键(Fn+Delete) ↑ 上箭头 ...
- 洛谷 P5664 Emiya 家今天的饭(84分)
题目传送门 解题思路: 对于每一个列c,f[i][j][k]表示到第i行,第c列选了j个,其它列一共选了k个,然后我们读题意发现只要j>k,那就一定是不合法的,然后统计所有方案,减去所有不合法方 ...
- python里类的概念
Python编程中类的概念可以比作是某种类型集合的描述,如"人类"可以被看作一个类,然后用人类这个类定义出每个具体的人--你.我.他等作为其对象.类还拥有属性和功能,属性即类本身的 ...
- MDK中在stm32下载出现error:flash download failed “cortex-m3”的问题
主要原因,以前用的是J-LINK ,现在用的是ST-LINK .MDK默认是J-LINK .所以在改了下载器.
- Tomcat server.xml常用配置 含有外带文件及默认host
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE server-xml [<!ENTITY ...
- 107.JsonResponse
JsonResponse类: 用来dump字符串成json字符串,然后返回将json字符串封装成Response对象返回给浏览器,并且它的Content-Type是application/json.示 ...
- android implementation 依赖第三方库
依赖第三方库
- 使用hexo+GitHub搭建个人博客的心得(含教程)
Author Email Yaoyao Liu yaoyaoliu@msn.com 前言 对于广大CS专业的学生和码农,找一个地方写博客,记录一些编程.配置环境.阅读论文的心得体会是一个很常见的习惯. ...
- Tensorflow学习教程------lenet多标签分类
本文在上篇的基础上利用lenet进行多标签分类.五个分类标准,每个标准分两类.实际来说,本文所介绍的多标签分类属于多任务学习中的联合训练,具体代码如下. #coding:utf-8 import te ...
- quartz定时定时任务执行两次
quartz框架没问题. 流程: sping-quartz配置 <?xml version="1.0" encoding="UTF-8"?> < ...