首页 > 其他分享 >JDK8 四大核心函数式接口及扩展接口总结

JDK8 四大核心函数式接口及扩展接口总结

时间:2023-02-03 17:22:39浏览次数:58  
标签:Function Predicate return 函数 接口 JDK8 Consumer

前言

 Java8的四大函数式接口及相关的扩展接口在日常使用中的频率也是非常多的,包括自己定义的函数式接口,在JDK1.8之前,我们定义的方法都是用来接收参数,然后自己根据参数传递实现逻辑。在1.8之后,可以通过参数传递一段行为代码,将公共的行为代码封装成一个函数式接口传递,可以减少很多代码量,在Stream的API中就有很多的体现,在此归纳总结一下。

 

函数式接口简介

函数式接口指的是有且只能有一个抽象方法,但是可以有多个非抽象方法的接口,这样的接口可以转换成Lambda表达式。在函数式接口中,可以添加上@FunctionalInterface注解标注这是一个函数式接口,此注解主要用于编译器在编译期检查该接口是否符合函数式接口的定义规范(即只能有一个抽象方法),如不符合,编译器则会报错提示。

 

四大核心函数式接口

Consumer-消费型接口

源码如下,此接口中的抽象方法则是accept,传入一个T参数,执行自定义逻辑将它消费掉,没有返回值。

@FunctionalInterface
public interface Consumer<T> {

    void accept(T t);

    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

 

示例,实现一个打印List的Consumer接口,传入不同的List将其打印。

 

有没有机智的同学发现,示例中的forEach()方法其参数就是一个Consumer接口,根据传入的集合将其遍历。

Consumer接口在JDK中的应用,此为Iterable接口中的forEach方法,ArrayList中的forEach就是重写了该方法。


default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}

 

Supplier-供给型接口

源码如下,此接口中方法只有一个无参的方法,返回一个T类型的结果。

@FunctionalInterface
public interface Supplier<T> {

    T get();
}

 

示例,实现一个返回随机数的Supplier接口,通过指定数量返回一个随机数集合。

 

Supplier接口在JDK中的应用,此为Optional类中的orElseGet方法。

public T orElseGet(Supplier<? extends T> other) {
    return value != null ? value : other.get();
}

 

Function-函数型接口

源码如下,此接口中的抽象方法为apply,传入一个T参数,返回一个R结果。

@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;
    }
}

 

示例,将字符串使用MD5加密后返回。

 

Function接口在JDK中的应用,此为Stream中的mapflatMap方法。

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);

 

Predicate-断言型接口

源码如下,抽象方法为test,传入一个T类型,返回一个固定类型为布尔值的方法。

@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);
    }
}

 

 示例,判断数字是否大于0。

 

Predicate接口在JDK中的应用,此为Stream中的filter方法。

Stream<T> filter(Predicate<? super T> predicate);

 

在StreamAPI中的应用

熟悉使用Stream的靓仔们肯定知道,它极大简化了我们的代码量,在其中就有很多频繁应用函数式接口的地方。

 

四大函数式接口总结

 

扩展接口

消费型接口-扩展接口

 

供给型接口-扩展接口

 

函数型接口-扩展接口

 

断言型接口-扩展接口

 

总结

以上就是四大内置核心函数式接口与各扩展接口的使用,可以涵盖工作中大部分的业务场景。如还有不满足业务场景的地方,hutool工具包中也有更多的扩展接口可使用,也可以自定义函数式接口,结合自身的业务使用,非常灵活强大,配合Lambda表达式和方法引用可以使代码更简洁,省略冗余的代码。

 

参考链接:

Java8新特性 | 四大函数式接口及其扩展接口

JDK8新特性第二篇:四大函数式接口【Function/Consumer/Supplier/Perdicate】、接口的扩展方法【default/static】

标签:Function,Predicate,return,函数,接口,JDK8,Consumer
From: https://www.cnblogs.com/-tang/p/17029633.html

相关文章

  • Java基础之面向对象——抽象类、接口、枚举
    抽象类     越是处于顶层定义的类,实际上可以进一步地进行抽象。抽象类里可以有抽象方法(也可以没有)。抽象类完全由子类来实现,父类中不需要提供实现。例如,对于该父类......
  • Jmeter+Maven接口自动化搭建
    1.Jmeter脚本录制/编写Jmeter脚本(不做描述)2.Maven项目配置1、创建一个Maven工程            2、在src/test目录下新建一个jmeter的目录,用来存......
  • strcpy函数
    strcpy,即stringcopy(字符串复制)的缩写。strcpy是C++/C语言语言的一个标准函数  ,strcpy把含有'\0'结束符(停止拷贝的终止条件)的字符串复制到另一个地址空间,返回值的类型为......
  • flea-jersey使用之Flea RESTful接口介绍
    FleaRESTful接口相关文档可参考FleaRESTful接口规范.docx,点击Viewraw即可下载1.总体概述FleaRESTful接口,即遵守REST式风格的接口,基于Jersey开发,遵循JAX-RS规......
  • JavaScript函数详解:匿名函数、具名函数、函数传参、不定参、返回值、JS预解析机制
     JavaScript函数详解:匿名函数、具名函数、函数传参、不定参、返回值、JS预解析机制  1.具名函数 定义: 调用:方式1:方法名();可以多次调用  ......
  • 前端——函数(匿名函数、自执行函数)
    前端——函数(匿名函数、自执行函数)FreshLemon_于2019-06-1117:11:49发布函数声明:functionbox(){}函数表达式:varbox=function(){};匿名函数:function(){}......
  • C++ 哈希表查询_进入哈希函数结界的世界
    1.前言哈希表或称为散列表,是一种常见的、使用频率非常高的数据存储方案。哈希表属于抽象数据结构,需要开发者按哈希表数据结构的存储要求进行API定制,对于大部分高级语言......
  • vue3中的setup函数
    setup函数是组合式API的入口setup函数是页面启动后的自执行函数页面中所涉及的变量和方法都需要下载setup函数中在setup中定义的变量,方法都需要return出去才可以使用,否则......
  • #Python 文本包含pandas的 Series.str.contains函数
    一:基础的函数组成’’‘Series.str.contains(pat,case=True,flags=0,na=nan,regex=True)’’'测试pattern或regex是否包含在Series或Index的字符串中。返回布尔值系列......
  • 闭区间可导函数在在两个端点处连续的证明
    如果一个函数在闭区间\([a,b]\)内可导,那么首先\(f^{'}\)在区间\((a,b)\)任意一点都存在,且如下两个极限存在\[\lim_{h\rightarrow0^+}\frac{f(a+h)-f(a)}{h}\\\lim_{h......