Java 8 特性 —— 函数式接口
函数式接口
概述:接口中只有一个抽象方法。
函数式接口,即适用于函数式编程场景的接口。而 Java 中的函数式编程体现就是 Lambda,所以函数式接口就是可以适用于 Lambda 使用的接口。只有确保接口中有且仅有一个抽象方法,Java 中的 Lambda 才能顺利地进行推导。
备注:“语法糖”是指使用更加方便,但是原理不变的代码语法。例如在遍历集合时使用的for-each语法,其实
底层的实现原理仍然是迭代器,这便是“语法糖”。从应用层面来讲,Java中的Lambda可以被当做是匿名内部
类的“语法糖”,但是二者在原理上是不同的。
格式
只要确保接口中有且仅有一个抽象方法即可
修饰符 interface 接口名称 {
public abstract 返回值类型 方法名称(可选参数信息);
// 其他非抽象方法内容
}
@FunctionalInterface注解
与@Override 注解的作用类似,Java8 中专门为函数式接口引入了一个新的注解: @FunctionalInterface 。该注解可用于一个接口的定义上,一旦使用该注解来定义接口,编译器将会强制检查该接口是否确实有且仅有一个抽象方法(但是可以有多个非抽象方法),否则将会报错,如下图。需要注意的是,即使不使用该注解,只要满足函数式接口的定义,这仍然是一个函数式接口,使用起来都一样。
自定义函数式接口
package com.boomoom; /**
* 自定义函数式接口
* 使用@FunctionalInterface可以说明该接口是函数式接口,但是不加,如果接口中只有一个抽象方法,这个接口也是函数式接口
* 也就是说函数式接口不以注解的存在而存在
*/
@FunctionalInterface
public interface MyFunctionalInterface { public abstract void show();
}
有参数,有返回值的自定义函数式接口
@FunctionalInterface
public interface Sumable {
int sum(int a, int b);
}
JDK1.8之后的某些函数式接口
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 的函数式编程。选取几个接口示例详解。
supplier生产数据函数式接口
目的是生产数据。
目前好像看不出来有什么用,但是好像和 jdk8 的 Stream 流有关。举个小例子:
package com.boomoom; import java.util.function.Supplier; /**
* 使用supplier函数式接口求数组的最大值
*/
public class ArrMaxValue { public static int getMaxValue(Supplier<Integer> sup){
return sup.get();
} public static void main(String[] args) {
// 创建数组
int[] arr = {100,20,50,30,99,101,-50}; int maxValue = getMaxValue(()->{
int max = arr[0];
for (int i : arr) {
if(i > max){
max = i;
}
}
return max;
}); System.out.println("数组中的最大值为:" + maxValue); // 数组中的最大值为:101
}
}
Consumer消费数据函数式接口
这个方法是用来消费数据的,如何消费,消费规则自己定义。
package com.boomoom; import java.util.function.Consumer; /**
* 使用Consumer函数式接口实现格式化输出
*/
public class ConsumerDemo {
public static void printInfo(String[] strArr, Consumer<String> con1, Consumer<String> con2) {
for (int i = 0; i < strArr.length; i++) {
con1.andThen(con2).accept(strArr[i]);
}
} public static void main(String[] args) {
String[] strArr = {"迪丽热巴,女", "郑爽,女", "杨紫,女"};
printInfo(strArr, (message) -> {
System.out.print("姓名:" + message.split(",")[0] + "。 ");
}, (message) -> {
System.out.println("性别:" + message.split(",")[1] + "。"); });
}
}
Predicate判断函数式接口
Predicate 接口中包含一个抽象方法:boolean test(T t) 。用于条件判断的场景。
默认方法:
package com.boomoom; import java.util.ArrayList;
import java.util.function.Predicate; public class PredicateDemo { /**
* 检查数组中的元素是否符合要求,满足要求加入List中并返回
* @param arr 需要判断的数组
* @param pre1 判断接口1,判断性别是否为女
* @param pre2 判断接口2,判断姓名长度是否大于2
* @return
*/
public static ArrayList<String> checkStar(String[] arr, Predicate<String> pre1, Predicate<String> pre2){
ArrayList<String> arrayList = new ArrayList<>();
for (int i = 0; i < arr.length; i++) {
boolean test = pre1.and(pre2).test(arr[i]);
if (test) {
arrayList.add(arr[i]);
}
}
return arrayList;
} public static void main(String[] args) {
// 创建数组
String[] arr = {"迪丽热巴,女","杨洋,男","李溪芮,女","郑爽,女"}; // 调用方法(Lambda表达式可以简化)
ArrayList<String> list = checkStar(arr,(str)-> str.split(",")[1].equals("女"),
(str)-> str.split(",")[0].length() > 2); // 遍历集合
for (String elem : list) {
System.out.print(elem + " ");
}
}
}
Function类型转换函数式接口
Function 接口中最主要的抽象方法为: R apply(T t) ,根据类型T的参数获取类型R的结果。
Function 接口中有一个默认的andThen 方法,用来进行组合操作。
package com.boomoom; import java.util.function.Function; public class FunctionDemo {
/**
* 将String分割,获得第二个元素,将数据转化为int,int数据加1000,再将int转化为String
* @param str 转化的数据
* @param fun1 String -> String
* @param fun2 String -> Integer
* @param fun3 Integer -> String
* @return 最后的String
*/
public static String convert(String str,
Function<String,String> fun1,
Function<String, Integer> fun2,
Function<Integer,String> fun3){ return fun1.andThen(fun2).andThen(fun3).apply(str);
} public static void main(String[] args) {
String str = convert("迪丽热巴,24",(s)->{
return s.split(",")[1];
},(s)->{
return Integer.parseInt(s) + 1000;
}, String::valueOf);
System.out.println(str);
}
}
参考:http://www.runoob.com/java/java8-functional-interfaces.html
https://www.cnblogs.com/wadmwz/p/9384660.html
Java 8 特性 —— 函数式接口的更多相关文章
- 用好JAVA中的函数式接口,轻松从通用代码框架中剥离掉业务定制逻辑
大家好,又见面了. 今天我们一起聊一聊JAVA中的函数式接口.那我们首先要知道啥是函数式接口.它和JAVA中普通的接口有啥区别?其实函数式接口也是一个Interface类,是一种比较特殊的接口类,这个 ...
- 【Java 8】函数式接口(一)—— Functional Interface简介
什么是函数式接口(Functional Interface) 其实之前在讲Lambda表达式的时候提到过,所谓的函数式接口,当然首先是一个接口,然后就是在这个接口里面只能有一个抽象方法. 这种类型的接 ...
- Java8 新特性 函数式接口
什么是函数式接口 函数式接口是Java8引用的一个新特性,是一种特殊的接口:SAM类型的接口(Single Abstract Method).但是它还是一个接口,只是有些特殊罢了. 函数式接口的 ...
- Java8 新特性----函数式接口,以及和Lambda表达式的关系
这里来讲解一下Java8 新特性中的函数式接口, 以及和Lambda 表达式的关系.看到过很多不少介绍Java8特性的文章,都会介绍到函数式接口和lambda表达式,但是都是分别介绍,没有将两者的关系 ...
- java8新特性-函数式接口详细讲解及案例
一.函数式接口 1.1 概念 函数式接口在Java中是指:有且仅有一个抽象方法的接口.函数式接口,即适用于函数式编程场景的接口.而Java中的函数式编程体现就是Lambda,所以函数式接口就是可 以适 ...
- 【Java 8】函数式接口(二)—— 四大函数接口介绍
前言 Java8中函数接口有很多,大概有几十个吧,具体究竟是多少我也数不清,所以一开始看的时候感觉一脸懵逼,不过其实根本没那么复杂,毕竟不应该也没必要把一个东西设计的很复杂. 几个单词 在学习了解之前 ...
- Java 之 常用函数式接口
JDK提供了大量常用的函数式接口以丰富Lambda的典型使用场景,它们主要在 java.util.function 包中被提供.下面是最简单的几个接口及使用示例. 一.Supplier 接口 java ...
- Java 中的函数式接口
java.util.function中定义了几组类型的函数式接口以及针对基本数据类型的子接口. Predicate -- 传入一个参数,返回一个bool结果, 方法为boolean test(T t) ...
- java中的函数式接口
是什么?? 有且只有一个抽象方法的接口 场景: 适用于函数式编程场景(使用lambda表达式编程)的接口,函数式接口可以适用于lambda使用的接口. 只有确保接口中有且只有一个抽象方法,java中的 ...
随机推荐
- spring boot整合mybatis方式二
方式二: pom文件导入maven依赖: <dependency> <groupId>org.springframework.boot</groupId> < ...
- 【Tomcat】Tomcat工作原理及简单模拟实现
Tomcat应该都不陌生,我们经常会把写好的代码打包放在Tomcat里并启动,然后在浏览器里就能愉快的调用我们写的代码来实现相应的功能了,那么Tomcat是如何工作的? 一.Tomcat工作原理 我们 ...
- IM多类型holder封装
如标题,这是一个在列表多类型视图时的一个简化封装方法,减少多余代码,提高复用性,更好迭代扩展,先看视图列表效果图 GitHub:https://github.com/1024477951/Fragme ...
- Android Material Design控件使用(一)——ConstraintLayout 约束布局
参考文章: 约束布局ConstraintLayout看这一篇就够了 ConstraintLayout - 属性篇 介绍 Android ConstraintLayout是谷歌推出替代PrecentLa ...
- DVWA 黑客攻防实战(十五) 绕过内容安全策略 Content Security Policy (CSP) Bypass
看到标题,是否有点疑惑 CPS 是什么东东.简单介绍一下就是浏览器的安全策略,如果 标签,或者是服务器中返回 HTTP 头中有 Content-Security-Policy 标签 ,浏览器会根据标签 ...
- 好代码是管出来的——使用GitHub
前面的文章介绍了Git的基本概念和用法,本文则是基于GitHub的一个实践介绍,主要内容有: GitHub简介 个人与组织 仓库的创建与维护 Fork与pull request 小结 GitHub简介 ...
- sqlserver安装报错:an error was encountered 数据无效
解决方法:下载的包损坏,重新下载包
- Review: Command-line about Git
Git shanzm
- File operations 1
1:只读(‘r' 和 ’rb'以字节读) f = open('d:\模特主妇护士班主任.txt',mode='r',encoding='UTF-8') content = f.read() print ...
- ubuntu18.04从零开始配置环境(jdk+tomcat+idea)到使用idea开发web应用和servlet
昨天吃了亏,搞了一下午才把环境配置好,故此将整个过程记录一下以防日后需要. 注意:因为我的博客模块的原因,所以我把图片压缩了一些,如果有看不清的, 可以 右键图片->在新标签页打开图片 目录: ...