JAVA8之函数式编程Function接口用法
作者:Zn昕 时间:2022-01-04 04:03:04
从这章开始,会介绍几个常用的函数式接口工具,首先先来看下这个大家族:
首先从Function接口开始介绍
一. 概述
该接口顾名思义,函数的意思,就像是数学,是给定一个参数然后返回结果.该类方法如下:
package java.util.function;
import java.util.Objects;
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static <T> Function<T, T> identity() {
return t -> t;
}
1. apply方法
该接口的唯一个抽象类是apply方法,接受一个类型的参数,有返回值.功能是将参数赋予相应的方法.
2. compose方法
默认方法,先用入参去调用apply方法,然后再用调用者去调用apply方法.调用的Object.requireNonNull是java7的新特性,如果before是null值的话直接抛出异常.
3. andThen方法
默认方法,与compose方法相反,先用调用者去调用apply方法,然后再用入参去调用apply方法.
4. identity方法
静态方法,java8新特性,返回当前正在执行的方法.
二. 示例
不难看出,除了第一个方法以外,其他三个方法的返回值都是Function,所以后面三个方法是可以链式调用(即用"."方法)的,就如建造者模式(Build)一样.理论讲完,上代码:
package com.yczuoxin.demo;
import java.util.function.Function;
public class FunctionTest {
public static void main(String[] args) {
// 先声明方法
Function<Integer, Integer> funcDouble = (n) -> n * 2;
Function<Integer, Integer> funcPlus2 = (n) -> n + 2;
System.out.println(funcDouble.apply(3));
System.out.println(funcPlus2.apply(3));
System.out.println(funcDouble.andThen(funcPlus2).apply(3));
System.out.println(funcDouble.compose(funcPlus2).apply(3));
System.out.println(Function.identity().compose(funcDouble).apply(8));
}
}
运行结果:
把计算过程也写在上面应该就能知道执行顺序了吧.
三. 总结
这个工具类感觉就是回到了学数学的场景,自己规定函数,然后调用函数,其实不仅仅可以调用一次andThen方法,后面还以加,只是没有写出来而已,大家可以自己去尝试一下.
补充知识:JAVA8之函数式编程Predicate接口
一.概述
先上这个接口的源码:
package java.util.function;
import java.util.Objects;
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
default Predicate<T> negate() {
return (t) -> !test(t);
}
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
1.test方法
该方法是接受一个传入类型,返回一个布尔值.此方法应用于判断.
2.and方法,or方法
该些方法接收的是一个Predicate类型参数,返回的也是一个Predicate类型.and方法用于两个判断是否都成立,与关系型运算符"&&"相似.而or方法则用于两个判断是否有一个成立.与关系型运算符"||"相似.
3.negate方法
该方法没有传入参数,返回一个Predicate类型.此方法用于对判断进行取反.与关系型云算法"!"相似.
4.isEqual方法
该方法接收一个Object对象,返回一个Predicate类型.此方法用于判断第一个test的方法与第二个test方法相同(equal).
二. 示例
写一个判断字符串的一个判断工具类,包含Predicate4种方法,并返回判断结果.
package com.yczuoxin.demo.predicate;
import java.util.function.Predicate;
public class PredicateUtil {
public static boolean judgeString(String str, Predicate<String> p){
if(null == str){
return false;
}
return p.test(str);
}
public static boolean judgeNoString(String str, Predicate<String> p){
if(null == str){
return false;
}
return p.negate().test(str);
}
public static boolean judgeAndDoubleString(String str, Predicate<String> p1, Predicate<String> p2){
if(null == str){
return false;
}
return p1.and(p2).test(str);
}
public static boolean judgeOrDoubleString(String str, Predicate<String> p1, Predicate<String> p2){
if(null == str){
return false;
}
return p1.or(p2).test(str);
}
}
测试字符串长度是否大于4的方法用例:
package com.yczuoxin.demo.predicate;
import java.util.function.Predicate;
public class PredicateTest {
public static void main(String[] args) {
String testString = "abcde";
// 判断字符串长度是否大于4
System.out.println(PredicateUtil.judgeString(testString,p->p.length()>4));
// 判断字符串长度是否大于4再取反
System.out.println(PredicateUtil.judgeNoString(testString,p->p.length()>4));
// 判断字符串长度是否大于4并且小于8
System.out.println(PredicateUtil.judgeAndDoubleString(testString,p->p.length()>4,p->p.length()<8));
// 判断字符串长度是否小于4并且大于8
System.out.println(PredicateUtil.judgeOrDoubleString(testString,p->p.length()<4,p->p.length()>8));
// 判断当前方法是否是"test"方法.
System.out.println(Predicate.isEqual("test").test("test"));
System.out.println(Predicate.isEqual("test").test("test1"));
}
}
测试结果:
三. 总结
Predicate适合在工具类和条件筛选的条件下使用,减少if...else的使用,并且使用灵活.
来源:https://blog.csdn.net/ycxzuoxin/article/details/80950931
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
Java 二分查找算法的实现
Spring Boot 集成Dubbo框架实例
SpringMVC解析JSON请求数据问题解析
![](https://img.aspxhome.com/file/2023/8/60578_0s.png)
Java语法中Lambda表达式无法抛出异常的解决
java实现图片写入高清字体及带边框的方法
elasticsearch分布式及数据的功能源码分析
![](https://img.aspxhome.com/file/2023/7/58087_0s.png)
android线程消息机制之Handler详解
![](https://img.aspxhome.com/file/2023/1/85961_0s.jpg)
Spring深入刨析声明式事务注解的源码
![](https://img.aspxhome.com/file/2023/6/61026_0s.png)
Android 判断某个Activity 是否在前台运行的实例
Flutter中http请求抓包的完美解决方案
![](https://img.aspxhome.com/file/2023/9/110729_0s.jpg)
详解Java中运算符及用法
java锁synchronized面试常问总结
![](https://img.aspxhome.com/file/2023/7/57917_0s.png)
SpringCloud分布式链路跟踪的方法
![](https://img.aspxhome.com/file/2023/6/59936_0s.png)
Java中Function的使用及说明
![](https://img.aspxhome.com/file/2023/5/58025_0s.png)
Spring Boot实现异步请求(Servlet 3.0)
java虚拟机钩子关闭函数addShutdownHook的操作
![](https://img.aspxhome.com/file/2023/6/61576_0s.jpg)
Mybatis注解实现多数据源读写分离详解
![](https://img.aspxhome.com/file/2023/1/62211_0s.jpg)