Java 8 函数式接口
函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。
函数式接口可以被隐式转换为 lambda 表达式。
Lambda 表达式和方法引用(实际上也可认为是Lambda表达式)上。
如定义了一个函数式接口如下:
@FunctionalInterface
interface GreetingService
{
void sayMessage(String message);
}
那么就可以使用Lambda表达式来表示该接口的一个实现(注:JAVA 8 之前一般是用匿名类实现的):
GreetingService greetService1 = message -> System.out.println("Hello " + message);
函数式接口可以对现有的函数友好地支持 lambda。
我们项目中用到了函数式接口:
接口定义:
 private Function<JudgeResultDto, AppealDetourDataDto> covertDetourDataDto = dataRequest -> {
        AppealDetourDataDto dataDto = new AppealDetourDataDto();
        BeanUtils.copyProperties(dataRequest, dataDto);
        return dataDto;
    };
接口引用:
if (judgeScenarios != null && JudgeScenarios.Detour_Order_After_Driving == JudgeScenarios.valueOf(judgeScenarios)) {
                JudgeResultDto dataRequest = JSONObject.parseObject(jsonMsg, JudgeResultDto.class);
                AppealDetourDataDto dataDto = covertDetourDataDto.apply(dataRequest);
                appealJudgeAcceptProvider.acceptAppeal(dataDto);
                //绕路事件埋点-mq消费绕路数据事件
                Cat.logEvent("detour.consumer.data.result", "success");
            }
JDK 1.8 之前已有的函数式接口:
- java.lang.Runnable
- java.util.concurrent.Callable
- java.security.PrivilegedAction
- java.util.Comparator
- java.io.FileFilter
- java.nio.file.PathMatcher
- java.lang.reflect.InvocationHandler
- java.beans.PropertyChangeListener
- java.awt.event.ActionListener
- javax.swing.event.ChangeListener
JDK 1.8 新增加的函数接口:
- java.util.function
java.util.function 它包含了很多类,用来支持 Java的 函数式编程,该包中的函数式接口有:
| 序号 | 接口 & 描述 | 
|---|---|
| 1 | BiConsumer<T,U> 代表了一个接受两个输入参数的操作,并且不返回任何结果 | 
| 2 | BiFunction<T,U,R> 代表了一个接受两个输入参数的方法,并且返回一个结果 | 
| 3 | BinaryOperator<T> 代表了一个作用于于两个同类型操作符的操作,并且返回了操作符同类型的结果 | 
| 4 | BiPredicate<T,U> 代表了一个两个参数的boolean值方法 | 
| 5 | BooleanSupplier 代表了boolean值结果的提供方 | 
| 6 | Consumer<T> 代表了接受一个输入参数并且无返回的操作 | 
| 7 | DoubleBinaryOperator 代表了作用于两个double值操作符的操作,并且返回了一个double值的结果。 | 
| 8 | DoubleConsumer 代表一个接受double值参数的操作,并且不返回结果。 | 
| 9 | DoubleFunction<R> 代表接受一个double值参数的方法,并且返回结果 | 
| 10 | DoublePredicate 代表一个拥有double值参数的boolean值方法 | 
| 11 | DoubleSupplier 代表一个double值结构的提供方 | 
| 12 | DoubleToIntFunction 接受一个double类型输入,返回一个int类型结果。 | 
| 13 | DoubleToLongFunction 接受一个double类型输入,返回一个long类型结果 | 
| 14 | DoubleUnaryOperator 接受一个参数同为类型double,返回值类型也为double 。 | 
| 15 | Function<T,R> 接受一个输入参数,返回一个结果。 | 
| 16 | IntBinaryOperator 接受两个参数同为类型int,返回值类型也为int 。 | 
| 17 | IntConsumer 接受一个int类型的输入参数,无返回值 。 | 
| 18 | IntFunction<R> 接受一个int类型输入参数,返回一个结果 。 | 
| 19 | IntPredicate :接受一个int输入参数,返回一个布尔值的结果。 | 
| 20 | IntSupplier 无参数,返回一个int类型结果。 | 
| 21 | IntToDoubleFunction 接受一个int类型输入,返回一个double类型结果 。 | 
| 22 | IntToLongFunction 接受一个int类型输入,返回一个long类型结果。 | 
| 23 | IntUnaryOperator 接受一个参数同为类型int,返回值类型也为int 。 | 
| 24 | LongBinaryOperator 接受两个参数同为类型long,返回值类型也为long。 | 
| 25 | LongConsumer 接受一个long类型的输入参数,无返回值。 | 
| 26 | LongFunction<R> 接受一个long类型输入参数,返回一个结果。 | 
| 27 | LongPredicate R接受一个long输入参数,返回一个布尔值类型结果。 | 
| 28 | LongSupplier 无参数,返回一个结果long类型的值。 | 
| 29 | LongToDoubleFunction 接受一个long类型输入,返回一个double类型结果。 | 
| 30 | LongToIntFunction 接受一个long类型输入,返回一个int类型结果。 | 
| 31 | LongUnaryOperator 接受一个参数同为类型long,返回值类型也为long。 | 
| 32 | ObjDoubleConsumer<T> 接受一个object类型和一个double类型的输入参数,无返回值。 | 
| 33 | ObjIntConsumer<T> 接受一个object类型和一个int类型的输入参数,无返回值。 | 
| 34 | ObjLongConsumer<T> 接受一个object类型和一个long类型的输入参数,无返回值。 | 
| 35 | Predicate<T> 接受一个输入参数,返回一个布尔值结果。 | 
| 36 | Supplier<T> 无参数,返回一个结果。 | 
| 37 | ToDoubleBiFunction<T,U> 接受两个输入参数,返回一个double类型结果 | 
| 38 | ToDoubleFunction<T> 接受一个输入参数,返回一个double类型结果 | 
| 39 | ToIntBiFunction<T,U> 接受两个输入参数,返回一个int类型结果。 | 
| 40 | ToIntFunction<T> 接受一个输入参数,返回一个int类型结果。 | 
| 41 | ToLongBiFunction<T,U> 接受两个输入参数,返回一个long类型结果。 | 
| 42 | ToLongFunction<T> 接受一个输入参数,返回一个long类型结果。 | 
| 43 | UnaryOperator<T> 接受一个参数为类型T,返回值类型也为T。 | 
函数式接口实例
Predicate <T> 接口是一个函数式接口,它接受一个输入参数 T,返回一个布尔值结果。
该接口包含多种默认方法来将Predicate组合成其他复杂的逻辑(比如:与,或,非)。
该接口用于测试对象是 true 或 false。
我们可以通过以下实例(Java8Tester.java)来了解函数式接口 Predicate <T> 的使用:
Java8Tester.java 文件
执行以上脚本,输出结果为:
$ javac Java8Tester.java
$ java Java8Tester
输出所有数据:
1
2
3
4
5
6
7
8
9
输出所有偶数:
2
4
6
8
输出大于 3 的所有数字:
4
5
6
7
8
9
2 篇笔记 写笔记
- erichuang - eri***su@qq.com - eval 函数可以写为如下格式: - private static void eval(List<Integer> list, Predicate<Integer> predicate) {
 list.stream().filter(predicate).forEach(System.out::println);
 }- 或者直接可以不用定义 eval 函数,使用: - list.stream().filter(n -> n > 3).forEach(System.out::println); - 来输出所有大于 3 的数字。 
- 关于 @FunctionalInterface 注解 - Java 8为函数式接口引入了一个新注解@FunctionalInterface,主要用于编译级错误检查,加上该注解,当你写的接口不符合函数式接口定义的时候,编译器会报错。 - 正确例子,没有报错: - @FunctionalInterface 
 interface GreetingService
 {
 void sayMessage(String message);
 }- 错误例子,接口中包含了两个抽象方法,违反了函数式接口的定义,Eclipse 报错提示其不是函数式接口。  - 提醒:加不加 @FunctionalInterface 对于接口是不是函数式接口没有影响,该注解只是提醒编译器去检查该接口是否仅包含一个抽象方法 - 函数式接口里允许定义默认方法 - 函数式接口里是可以包含默认方法,因为默认方法不是抽象方法,其有一个默认实现,所以是符合函数式接口的定义的; - 如下代码不会报错: - @FunctionalInterface 
 interface GreetingService
 {
 void sayMessage(String message); default void doSomeMoreWork1()
 {
 // Method body
 } default void doSomeMoreWork2()
 {
 // Method body
 }
 }- 函数式接口里允许定义静态方法 - 函数式接口里是可以包含静态方法,因为静态方法不能是抽象方法,是一个已经实现了的方法,所以是符合函数式接口的定义的; - 如下代码不会报错: - @FunctionalInterface 
 interface GreetingService
 {
 void sayMessage(String message);
 static void printHello(){
 System.out.println("Hello");
 }
 }- 函数式接口里允许定义 java.lang.Object 里的 public 方法 - 函数式接口里是可以包含Object里的public方法,这些方法对于函数式接口来说,不被当成是抽象方法(虽然它们是抽象方法);因为任何一个函数式接口的实现,默认都继承了 Object 类,包含了来自 java.lang.Object 里对这些抽象方法的实现; - 如下代码不会报错: - @FunctionalInterface 
 interface GreetingService
 {
 void sayMessage(String message); @Override
 boolean equals(Object obj);
 }
Java 8 函数式接口的更多相关文章
- Java 8 新特性-菜鸟教程 (3) -Java 8 函数式接口
		Java 8 函数式接口 函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口. 函数式接口可以被隐式转换为lambda表达式. 函数式接 ... 
- Java 8函数式接口functional interface的秘密
		Java 8函数式接口functional interface的秘密 2014年10月29日 17:52:55 西瓜可乐520 阅读数:3729 目录 [−] JDK 8之前已有的函数式接口 新定 ... 
- Java常用函数式接口--Consumer接口andThen()方法使用案例(二)
		Java常用函数式接口--Consumer接口使用案例 
- Java常用函数式接口--Predicate接口使用案例
		Java常用函数式接口--Predicate接口使用案例 该方法可以使用and来优化: 调用: 
- Java之函数式接口@FunctionalInterface详解(附源码)
		Java之函数式接口@FunctionalInterface详解 函数式接口的定义 在java8中,满足下面任意一个条件的接口都是函数式接口: 1.被@FunctionalInterface注释的接口 ... 
- JAVA 8 函数式接口 - Functional Interface
		什么是函数式接口(Functional Interface) 其实之前在讲Lambda表达式的时候提到过,所谓的函数式接口,当然首先是一个接口,然后就是在这个接口里面只能有一个抽象方法. 这种类型的接 ... 
- Java之函数式接口
		函数式接口 概述:接口中只有一个抽象方法 下面介绍的可能很抽象,理解不了,至少在我看来单独的这几个借口是没有用的,跟最下面说的 Stream流一起用才会有效果 函数式接口,即适用于函数式编程场景的接口 ... 
- JAVA 8 函数式接口--Consumer
		从JDK8开始java支持函数式编程,JDK也提供了几个常用的函数式接口,这篇主要介绍Consumer接口.文本介绍的顺序依次为: 源码介绍 使用实例 jdk内对Consumer的典型使用 扩展类介绍 ... 
- Java 关于函数式接口与Lambda表达式之间的关系
		java是一种面向对象的语言,java中的一切都是对象,即数组,每个类创建的实例也是对象.在java中定义的函数或方法不可能完全独立,也不能将方法函数作为参数或返回值给实例. 在java7及以前,我们 ... 
随机推荐
- WPF中修改DataGrid单元格值并保存
			编辑DataGrid中的单元格的内容然后保存是非常常用的功能.主要涉及到的方法就是DataGrid的CellEditEnding 和BeginningEdit .其中BeginningEdit 是当 ... 
- Oracle hint之ORDERED和USE_NL
			Hint:ORDERED和USE_NL ORDERED好理解,就是表示根据 from 后面表的顺序join,从左到右,左边的表做驱动表 use_nl(t1,t2):表示对表t1.t2关联时采用嵌套循环 ... 
- spring程序打包使用该插件,不然容易报错xsd找不到
			<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade ... 
- $.each遍历实现延时
			今天做项目时需要一功能,如题..... $.each(json, function(idx, obj) { setTimeout(function () {downloadFile(obj.fileK ... 
- 路飞学城-Python开发集训-第4章
			学习心得: 学习笔记: 在python中一个py文件就是一个模块 模块好处: 1.提高可维护性 2.可重用 3.避免函数名和变量名冲突 模块分为三种: 1.内置标准模块(标准库),查看所有自带和第三方 ... 
- 【vue】vue +element 搭建项目,在使用InputNumber 计数器时遇到的问题
			自己遇到的坑: InputNumber 计数器的change事件定义时如果不传入参数value,会产生this.num不同步的问题 <template> <el-input-numb ... 
- 18.JAVA经典编程题(50题及答案)
			用oop做一个进销存系统:1.货物对象属性:编号(唯一),名称,单价,类别,厂家,厂家地址,厂家联系方式,库存,最后进货时间2.功能:登录,入库,出库,库存查询,操作记录查询3.功能描述:登录:管理员 ... 
- Python 中的浅拷贝和深拷贝
			1. 列表和字典,直接赋值,都是浅拷贝,即赋值双方指向同一地址,因为 Python 对可变对象按引用传递. >>> a = [1, 2, 3] >>> b = a ... 
- php 数组元素快速去重
			1.使用array_unique方法进行去重 对数组元素进行去重,我们一般会使用array_unique方法,使用这个方法可以把数组中的元素去重. <?php $arr = array(,,,, ... 
- Netty入门(三)之web服务器
			Netty入门(三)之web服务器 阅读前请参考 Netty入门(一)之webSocket聊天室 Netty入门(二)之PC聊天室 有了前两篇的使用基础,学习本文也很简单!只需要在前两文的基础上稍微改 ... 
 
			
		 Java 8 新特性
 Java 8 新特性