java中functional interface的分类和使用
文章目录
- 简介
- Functional Interface
- Function:一个参数一个返回值
- BiFunction:接收两个参数,一个返回值
- Supplier:无参的Function
- Consumer:接收一个参数,不返回值
- Predicate:接收一个参数,返回boolean
- Operator:接收和返回同样的类型
- 总结
简介
java 8引入了lambda表达式,lambda表达式实际上表示的就是一个匿名的function。
在java 8之前,如果需要使用到匿名function需要new一个类的实现,但是有了lambda表达式之后,一切都变的非常简介。
我们看一个之前讲线程池的时候的一个例子:
//ExecutorService using classExecutorService executorService = Executors.newSingleThreadExecutor();executorService.submit(new Runnable() {@Overridepublic void run() {log.info("new runnable");}});
executorService.submit需要接收一个Runnable类,上面的例子中我们new了一个Runnable类,并实现了它的run()方法。
上面的例子如果用lambda表达式来重写,则如下所示:
//ExecutorService using lambdaexecutorService.submit(()->log.info("new runnable"));
看起是不是很简单,使用lambda表达式就可以省略匿名类的构造,并且可读性更强。
那么是不是所有的匿名类都可以用lambda表达式来重构呢?也不是。
我们看下Runnable类有什么特点:
@FunctionalInterface
public interface Runnable
Runnable类上面有一个@FunctionalInterface注解。这个注解就是我们今天要讲到的Functional Interface。
Functional Interface
Functional Interface是指带有 @FunctionalInterface 注解的interface。它的特点是其中只有一个子类必须要实现的abstract方法。如果abstract方法前面带有default关键字,则不做计算。
其实这个也很好理解,因为Functional Interface改写成为lambda表达式之后,并没有指定实现的哪个方法,如果有多个方法需要实现的话,就会有问题。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}
Functional Interface一般都在java.util.function包中。
根据要实现的方法参数和返回值的不同,Functional Interface可以分为很多种,下面我们分别来介绍。
Function:一个参数一个返回值
Function接口定义了一个方法,接收一个参数,返回一个参数。
@FunctionalInterface
public interface Function<T, R> {/*** Applies this function to the given argument.** @param t the function argument* @return the function result*/R apply(T t);
一般我们在对集合类进行处理的时候,会用到Function。
Map<String, Integer> nameMap = new HashMap<>();Integer value = nameMap.computeIfAbsent("name", s -> s.length());
上面的例子中我们调用了map的computeIfAbsent方法,传入一个Function。
上面的例子还可以改写成更短的:
Integer value1 = nameMap.computeIfAbsent("name", String::length);
Function没有指明参数和返回值的类型,如果需要传入特定的参数,则可以使用IntFunction, LongFunction, DoubleFunction:
@FunctionalInterface
public interface IntFunction<R> {/*** Applies this function to the given argument.** @param value the function argument* @return the function result*/R apply(int value);
}
如果需要返回特定的参数,则可以使用ToIntFunction, ToLongFunction, ToDoubleFunction:
@FunctionalInterface
public interface ToDoubleFunction<T> {/*** Applies this function to the given argument.** @param value the function argument* @return the function result*/double applyAsDouble(T value);
}
如果要同时指定参数和返回值,则可以使用DoubleToIntFunction, DoubleToLongFunction, IntToDoubleFunction, IntToLongFunction, LongToIntFunction, LongToDoubleFunction:
@FunctionalInterface
public interface LongToIntFunction {/*** Applies this function to the given argument.** @param value the function argument* @return the function result*/int applyAsInt(long value);
}
BiFunction:接收两个参数,一个返回值
如果需要接受两个参数,一个返回值的话,可以使用BiFunction:BiFunction, ToDoubleBiFunction, ToIntBiFunction, ToLongBiFunction等。
@FunctionalInterface
public interface BiFunction<T, U, R> {/*** Applies this function to the given arguments.** @param t the first function argument* @param u the second function argument* @return the function result*/R apply(T t, U u);
我们看一个BiFunction的例子:
//BiFunctionMap<String, Integer> salaries = new HashMap<>();salaries.put("alice", 100);salaries.put("jack", 200);salaries.put("mark", 300);salaries.replaceAll((name, oldValue) ->name.equals("alice") ? oldValue : oldValue + 200);
Supplier:无参的Function
如果什么参数都不需要,则可以使用Supplier:
@FunctionalInterface
public interface Supplier<T> {/*** Gets a result.** @return a result*/T get();
}
Consumer:接收一个参数,不返回值
Consumer接收一个参数,但是不返回任何值,我们看下Consumer的定义:
@FunctionalInterface
public interface Consumer<T> {/*** Performs this operation on the given argument.** @param t the input argument*/void accept(T t);
看一个Consumer的具体应用:
//ConsumernameMap.forEach((name, age) -> System.out.println(name + " is " + age + " years old"));
Predicate:接收一个参数,返回boolean
Predicate接收一个参数,返回boolean值:
@FunctionalInterface
public interface Predicate<T> {/*** Evaluates this predicate on the given argument.** @param t the input argument* @return {@code true} if the input argument matches the predicate,* otherwise {@code false}*/boolean test(T t);
如果用在集合类的过滤上面那是极好的:
//PredicateList<String> names = Arrays.asList("A", "B", "C", "D", "E");List<String> namesWithA = names.stream().filter(name -> name.startsWith("A")).collect(Collectors.toList());
Operator:接收和返回同样的类型
Operator接收和返回同样的类型,有很多种Operator:UnaryOperator BinaryOperator ,DoubleUnaryOperator, IntUnaryOperator, LongUnaryOperator, DoubleBinaryOperator, IntBinaryOperator, LongBinaryOperator等。
@FunctionalInterface
public interface IntUnaryOperator {/*** Applies this operator to the given operand.** @param operand the operand* @return the operator result*/int applyAsInt(int operand);
我们看一个BinaryOperator的例子:
//OperatorList<Integer> values = Arrays.asList(1, 2, 3, 4, 5);int sum = values.stream().reduce(0, (i1, i2) -> i1 + i2);
总结
Functional Interface是一个非常有用的新特性,希望大家能够掌握。
本文的例子:https://github.com/ddean2009/learn-java-streams/tree/master/functional-interface
更多精彩内容且看:
- 区块链从入门到放弃系列教程-涵盖密码学,超级账本,以太坊,Libra,比特币等持续更新
- Spring Boot 2.X系列教程:七天从无到有掌握Spring Boot-持续更新
- Spring 5.X系列教程:满足你对Spring5的一切想象-持续更新
- java程序员从小工到专家成神之路(2020版)-持续更新中,附详细文章教程
更多内容请访问 www.flydean.com
java中functional interface的分类和使用相关推荐
- functional java_java中functional interface的分类和使用详解
java 8引入了lambda表达式,lambda表达式实际上表示的就是一个匿名的function. 在java 8之前,如果需要使用到匿名function需要new一个类的实现,但是有了lambda ...
- 【Objective-C】java中的interface与Objective-C中的interface的区别
java中的interface interface叫做接口,是一种特殊的抽象类 一个接口中,所有方法为公开.抽象方法:所有的属性都是公开.静态.常量. 一个类只能继承一个类,但是能实现多个接口,这样可 ...
- java中常见的数据结构分类
自己总结了下java中常见的数据结构和分类 在这里,我总结了list中数据结构对应我们所学的线性表,属于顺序存储还是链式存储,但没有总结set数据结构对应我们所学的哪一种(按理说应该是集合),是因为t ...
- Java 中按文件名称分类,按文件大小分类,按照文件类型分类,按照最后修改时间分类的工具类
在此博客中用到了文件操作的工具类,可以连接 Java中实现复制文件到文件,复制文件到文件夹,复制文件夹到文件,删除文件,删除文件夹,移动文件,移动文件夹的工具类 package cn.edu.hact ...
- Java 中接口 interface 实例介绍
接口(interface) 有时必须从几个类中派生出一个子类,继承它们所有的属性和方法.但是,Java不支持多重继承.有了接口,就可以得到多重继承的效果. 接口(interface)是抽象方法和常量值 ...
- java中的interface
转载: Java不支持多重继承,即一个类只能有一个父类 为了克服单继承的缺点,Java使用了接口,一个类可以实现多个接口 接口是抽象方法和常量值定义的集合,是一种特殊的抽象类 接口中只包含常量和方法的 ...
- Java中常见流的分类及简单讲解
流在Java中是指计算中流动的缓冲区. 从外部设备流向中央处理器的数据流成为"输入流",反之成为"输出流". 字符流和字节流的主要区别: 1.字节流读取的时候, ...
- Java中IO流的分类和BIO,NIO,AIO的区别
到底什么是IO 我们常说的IO,指的是文件的输入和输出,但是在操作系统层面是如何定义IO的呢?到底什么样的过程可以叫做是一次IO呢? 拿一次磁盘文件读取为例,我们要读取的文件是存储在磁盘上的,我们的目 ...
- java中abstract,interface,final,static的区别
2019独角兽企业重金招聘Python工程师标准>>> 关键字: abstract, interface, final, static 一,抽象类:abstract 1,只要有一个或 ...
最新文章
- 用户态线程在AI中的应用
- groupby elasticsearch
- raft算法学习(一):角色概念以及选举过程
- 零基础带你学习MySQL—创建数据库(一)
- Atitit nlp 自然语言处理attilax总结 目录 1.1. 主要范畴	1 1.2. 研究难点	2 2. Ati涉及的领域(文档 tts 分词 抽取 摘要 检索)	2 3. Atit
- win7无法识别linux usb设备,win7无法安装usb驱动解决工具
- 蜂鸣器基本介绍及实现程序
- 电脑怎么录屏,什么录屏软件最好
- 基于FPGA的并行PRBS实现方法
- 腾讯云 Debian11 bullseye 源
- 【Android】HAL层浅析
- 从技术角度谈如何开发一款微信联网小游戏
- web编程(三)显示html网页
- Windows10 通过隧道进行远程桌面连接
- 传销分子为什么喜欢国学? PS:尽信书不如无书!
- Mysql官方网站到底该如何下载、安装?(超详细教程)
- 在Adapter里子线程更新UI线程
- 游戏静态HTML网页作业作品 大学生游戏介绍网页设计制作成品 简单DIV CSS布局网站
- 未在服务器上找到sql安装程序文件,MS SQL Server 2000/以前的某个程序安装已在安装计算机上创建挂起的文件操作。...
- 智能网联汽车专业术语