前言

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】

JDK8 四大核心函数式接口及扩展接口总结的更多相关文章

  1. JDK8新特性03 Lambda表达式03_Java8 内置的四大核心函数式接口

    import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.functio ...

  2. Java8内置的四大核心函数式接口

    package java_8; import org.junit.Test; import java.util.ArrayList; import java.util.Arrays; import j ...

  3. Java8新特性 - Java内置的四大核心函数式接口

    Java内置的四大核心函数式接口 Consumer:消费型接口 对类型为T的对象应用操作,包含方法:void accept(T t) public class TestLambda02 { publi ...

  4. java 8内置的四大核心函数式接口

    Consumer<T> : 消费性接口 返回值  void accept(T t); public void happy(double money, Consumer<Double& ...

  5. java8 四大核心函数式接口Function、Consumer、Supplier、Predicate(转载)

    Function<T, R> T:入参类型,R:出参类型 调用方法:R apply(T t); 定义函数示例:Function<Integer, Integer> func = ...

  6. lambda表达式与函数式(FunctionalInterface)接口

    一.lambda表达式 lambda表达式 Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递).使用它可以写出更简洁.更 灵活的代码. ...

  7. Spring8中lambda表达式的学习(Function接口、BiFunction接口、Consumer接口)

    代码重构,为了确保功能的等效性,梳理代码时,发现如下代码: public SingleRespTTO fundI(SingleReqTTO request) throws Exception { re ...

  8. Asp.net 面向接口可扩展框架之核心容器(含测试代码下载)

    新框架的容器部分终于调通了!容器实在太重要了,所以有用了一个名词叫“核心容器”. 容器为什么那么重要呢?这个有必要好好说道说道. 1.首先我们从框架名称面向接口编程说起,什么是面向接口编程?(这个度娘 ...

  9. hibernate核心接口,和扩展接口。回顾笔记,以前没记,现在补上,纯手工敲的。

    hibernate核心接口: 所有的hibernate应用都会访问hibernate的5个核心接口 1,Configuration接口 Configuration用于配置并且根启动Hibernate. ...

  10. java8新特性——四大内置核心函数式接口

    在前面几篇简单介绍了一些Lambda表达式得好处与语法,我们知道使用Lambda表达式是需要使用函数式接口得,那么,岂不是在我们开发过程中需要定义许多函数式接口,其实不然,java8其实已经为我们定义 ...

随机推荐

  1. 测试开发jmeter forEach控制器

    测试开发jmeter forEach控制器 forEach控制器的使用场景:主要是对大量数据轮询就行接口请求 forEach控制器的使用前提:将数据进行参数化 测试开发jmeter forEach控制 ...

  2. 云原生之旅 - 9)云原生时代网关的后起之秀Envoy Proxy 和基于Envoy 的 Emissary Ingress

    前言 前一篇文章讲述了基于Nginx代理的Kuberenetes Ingress Nginx[云原生时代的网关 Ingress Nginx]这次给大家介绍下基于Envoy的 Emissary Ingr ...

  3. 幂次方表达:p1010

    1 题目ID: P1010 [NOIP1998 普及组] 幂次方 2 题目描述: 任何一个正整数都可以用 22 的幂次方表示.例如 137=2^7+2^3+2^0137=27+23+20. 同时约定方 ...

  4. Azure Devops Create Project TF400711问题分析解决

    前几天,团队使用Azure Devops创建团队项目出了一个奇怪的错误: TF400797: 作业扩展具有一个未处理的错误: Microsoft.TeamFoundation.Framework.Se ...

  5. 面试 考察网络请求HTTP相关知识(第六天!)

    01.HTTP 常⻅的状态码有哪些? 1xx 服务器收到请求 2xx 请求成功         ---   200 成功状态码 3xx 重定向            ---  301永久重定向,浏览器 ...

  6. 本地GoLand编辑与调试远端服务器上的代码

    Goland是专为Go开发人员构建的跨平台IDE,功能非常强大,拥有强大的代码洞察力,帮助所有Go开发人员即时错误检测和修复建议,快速和安全的重构,一步撤销,智能代码完成,死代码检测和文档提示,让您创 ...

  7. [排序算法] 简单选择排序 (C++)

    简单选择排序原理 简单选择排序 SelectSort 是一种十分直观地排序方法.其原理是每次从未排序的元素中找到当前最小的元素,放在当前未排序序列的首位.一直重复操作直至最后未排序的元素个数为 0,即 ...

  8. tp6 requset获取参数的方式

    第一种:获取全部参数的值 request()->param() 1 第二种:获取排除某些字段的值,即获取其他值 request()->except(['serverToken','logi ...

  9. Js前端导出csv

    var myMemory = myObjectStore.objectStore; var myDataArray = myMemory.data; var myCsvString = "\ ...

  10. 《浅谈亚 log 数据结构在 OI 中的应用》阅读随笔

    这篇又长长长了! \(8435\to 8375\to 9729\) 早就馋这篇了!终于学了( 压位 Trie 确实很好写啊 但是总感觉使用范围不是很广的样子 似乎是见的题少 原文里都在用 \(\log ...