死磕Lambda表达式(二):Lambda的使用
城市就是森林,每一个男人都是猎手,每一个女人都是陷阱。——《三体》
在哪使用Lambda表达式?
在上一篇文章(传送门)中介绍了Lambda表达式的基本语法,其中的举了一个Lambda表达式的例子,就是按照品牌给口罩列表进行排序:
maskList.sort((Mask o1, Mask o2) -> o1.getBrand().compareTo(o2.getBrand()));
这里使用的sort方法的参数类型是Comparator<T>,我们就是把Lambda表达式作为Comparator<T>传入sort方法中的。Comparator<T>就是一个函数式接口,那么什么是函数式接口?
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
函数式接口
函数式接口就是有且仅有一个抽象方法的接口。上面提到的Comparator<T>接口,虽然有很多默认方法,但有且仅有一个抽象方法compare,所以它仍然是一个函数式接口。再举个例子:
package java.util.concurrent;
@FunctionalInterface
public interface Callable<V> {
V call() throws Exception;
}
Callable接口只有一个call抽象方法,所以它也是函数式接口。
你可以已经发现了,Callable接口上有一个注解@FunctionalInterface,该注解用于标志该接口是一个函数式接口。如果你编写了一个不是函数式接口的接口,并且加了@FunctionalInterface注解,编译就会报错,需要注意一下。
看了以上的例子,是不是撸胳膊挽袖子准备大干一场?别急,检验出真知,我们先简单测试一下。以下三个接口,哪些是函数式接口,哪些不是函数式接口?
- Runnable
package java.lang;
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
- Task
package com.sun.jmx.snmp.tasks;
public interface Task extends Runnable {
public void cancel();
}
- Serializable
package java.io;
public interface Serializable {
}
请思考片刻…
.
.
.

.
.
.
宣布答案:
Runnable只有一个抽象方法run,所以是函数式接口Task有两个抽象方法,分别是自己的cancel方法和从Runnable继承而来的run方法,所以不是函数式接口。Serializable没有任何一个方法,所以不是函数式接口。
怎么样?都答对了嘛?
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
实现函数式接口
了解了什么是函数式接口以后,我们就可以直接使用Lambda表达式为函数式接口提供实现了,并且还可以把整个Lambda表达式作为函数式接口的实例。比如上面提到的Runnable接口,我们就是这样直接赋值:
Runnable runnable = () -> {
System.out.println("万猫学社");
};
到目前为止,我们已经知道在哪使用Lambda表达式,那么该如何正确的使用Lambda表达式呢?
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
怎么使用Lambda表达式?
从上面Runnable接口实例的例子中,可以看出:Runnable接口的run方法没有入参没有返回,该方法的签名是() -> void;Lambda表达式同样的也没有入参没有返回,该表达式的签名是() -> void。
也就是说:函数式接口的抽象方法的签名和Lambda表达式的签名必须一致。
再比如,按照品牌给口罩列表进行排序的例子,Comparator<T>接口的compare方法的签名是(T ,T) -> int,Lambda表达式的签名同样也是(T ,T) -> int。
为了加深理解,我们再来做个小测试,看看哪些代码正确使用了Lambda表达式?
Callable
Callable<String> callable = () -> {
return "万猫学社";
};
Runnable
Runnable runnable = () -> {
return "万猫学社";
};
Comparator<Mask>
maskList.sort((Mask o1, Mask o2) -> {
if (o1.getBrand().equals(o2.getBrand())) {
return o1.getType().compareTo(o2.getType());
} else {
return o1.getBrand().compareTo(o2.getBrand());
}
});
请思考片刻…
.
.
.

.
.
.
宣布答案:
Callable:正确,Lambda表达式的签名是() -> String,与Callable<String>接口的唯一抽象方法call的签名匹配,所以是正确的。Runnable:错误,Lambda表达式的签名是() -> String,但是Runnable接口的唯一抽象方法run的签名是() -> void,两者不匹配,所以是错误的。Comparator<Mask>:正确,Lambda表达式的签名是(Mask, Mask) -> int,与Comparator<Mask>接口的唯一抽象方法compare的签名匹配,所以是正确的。
怎么样?都答对了嘛?
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
总结
有且仅有一个抽象方法的接口叫做函数式接口,Lambda表达式可以直接作为函数式接口的实例,函数式接口的抽象方法的签名和Lambda表达式的签名必须一致。
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
《死磕Lambda表达式》系列
- 死磕Lambda表达式(一):初识Lambda
- 死磕Lambda表达式(二):Lambda的使用
- 死磕Lambda表达式(三):更简洁的Lambda
- 死磕Lambda表达式(四):常用的函数式接口
- 死磕Lambda表达式(五):Comparator复合
- 死磕Lambda表达式(六):Consumer、Predicate、Function复合
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
死磕Lambda表达式(二):Lambda的使用的更多相关文章
- C#中分别对委托、匿名方法、Lambda表达式、Lambda表达式树以及反射执行同一方法的过程进行比较。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- C#3.0之神奇的Lambda表达式和Lambda语句
“Lambda 表达式”是一个匿名函数,它可以包含表达式和语句,并且可用于创建委托或表达式目录树类型.所有 Lambda 表达式都使用 Lambda 运算符 =>,该运算符读为“goes to” ...
- 一生挚友redo log、binlog《死磕MySQL系列 二》
系列文章 原来一条select语句在MySQL是这样执行的<死磕MySQL系列 一> 一生挚友redo log.binlog<死磕MySQL系列 二> 前言 咔咔闲谈 上期根据 ...
- Java 8 Lambda 表达式(二)
lambdas 实现 Runnable 接口 下面是使用 lambdas 来实现 Runnable 接口的示例: // 1.1使用匿名内部类 new Thread(new Runnable() { @ ...
- lambda表达式 <二>
概念了解: 1.什么是匿名委托(匿名方法的简单介绍.为什么要用匿名方法) 2.匿名方法的[拉姆达表达式]方法定义 3.匿名方法的调用(匿名方法的参数传递.使用过程中需要注意什么) 什么是匿名方法? 匿 ...
- Lambda表达式和Lambda表达式树
LINQ的基本功能就是创建操作管道,以及这些操作需要的任何状态. 为了富有效率的使用数据库和其他查询引擎,我们需要一种不同的方式表示管道中的各个操作.即把代码当作可在编程中进行检查的数据. Lambd ...
- 匿名函数 lambda表达式(lambda expression)
阅读g2log时,发现有两行代码居然看不懂. 1. auto bg_call = [this, log_directory]() {return pimpl_->backgroundChang ...
- java8 快速入门 lambda表达式 Java8 lambda表达式10个示例
本文由 ImportNew - lemeilleur 翻译自 javarevisited.欢迎加入翻译小组.转载请见文末要求. Java 8 刚于几周前发布,日期是2014年3月18日,这次开创性的发 ...
- Lambda(二)lambda表达式使用
Lambda(二)lambda表达式使用 Lambda 表达式组成: /* param list arrow lambda body (o1,o2) -> o1.getColor().Compa ...
- 夯实Java基础(二十二)——Java8新特性之Lambda表达式
1.前言 Java 8于14年发布到现在已经有5年时间了,经过时间的磨练,毫无疑问,Java 8是继Java 5(发布于2004年)之后的又一个非常最重要的版本.因为Java 8里面出现了非常多新的特 ...
随机推荐
- linux下用firefox打开csdn故障解决办法
问题:浏览器打开csdn时博客浏览不全,没有了排版 解决办法: 1.下载一个安装包 命令:epel-release-7-11.noarch.rpm: epel-release-7-11.noarch ...
- [LC] 322. Coin Change
You are given coins of different denominations and a total amount of money amount. Write a function ...
- JacksonConfig
package org.linlinjava.litemall.core.config; import com.fasterxml.jackson.annotation.JsonInclude; im ...
- day34-进程
#进程是程序的运行,程序不运行不产生进程. #1.进程的并行与并发: # 并行:是指两者同时执行,比如赛跑,两人都在不停的往前跑.(资源够用,比如三个线程,四核的cpu) # 并发:是指资源有限的情况 ...
- qsub|pasta|
cd /xxx/genome_stat/Annotation ln -s /xxx/02.annotation/gff_v2/*.homolog.v2.gff /xxx/genome_stat/Ann ...
- Java面试题2-附答案
JVM的内存结构 根据 JVM 规范,JVM 内存共分为虚拟机栈.堆.方法区.程序计数器.本地方法栈五个部分. 1.Java虚拟机栈: 线程私有:每个方法在执行的时候会创建一个栈帧,存储了局部变量表, ...
- LG_2967_[USACO09DEC]视频游戏的麻烦Video Game Troubles
题目描述 Farmer John's cows love their video games! FJ noticed that after playing these games that his c ...
- django框架基础-django模板语言-长期维护
################## 常用的模板语言 ####################### # django的模板语言, # # 只需要记两种特殊符号: # # {{ } ...
- top和margin-top的区别
1.top等为绝对定位,需与position:absolute一起用才有效:而margin-top为相对定位: 2.绝对定位一般情况下以body为标准:若父元素设置position:relative, ...
- OpenCV 霍夫线变换
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #i ...