Java 函数式编程(常用接口)

【java学习】java8新特性:stream、Lambda函数、接口的默认方法和类方法、函数式接口、Optional、DateTime 1,概念java.util.stream是java8新特性。 java.util.stream与java.io包里的 InputStream 和 OutputStream 是完全不同的概念。 Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数据操作 (bul............ 阅读详情

        之前已经介绍过了Java8函数式变成及Lambda表达式,感兴趣可以看看,地址:Java8函数式编程(Lambda表达式)_琅琊之榜PJ的博客-优快云博客

 本文主要介绍一下常用的接口及用法,先来看一个表格:

 本文主要选取几个常用的:Supplier<T>、Consumer<T>、Function<T,R>、Predicate<T>

在此之前,再来了解一下@FunctionalInterface注解。

一、@FunctionalInterface注解

        一种信息注释类型,用于指示接口类型声明是Java语言规范定义的函数接口。从概念上讲,函数接口只有一个抽象方法。由于默认方法有一个实现,所以它们不是抽象的。如果一个接口声明了一个覆盖java.lang.Object的一个公共方法的抽象方法,那么这也不计入该接口的抽象方法计数,因为该接口的任何实现都将具有来自java.lang.Oobject或其他地方的实现。

        注意,函数接口的实例可以使用lambda表达式、方法引用或构造函数引用创建。

        如果使用此注解类型对类进行注解,则编译器需要生成错误消息,除非类型是接口类型,而不是注解类型、枚举或类。

        带注解的类型满足功能接口的要求。

        但是,无论接口声明中是否存在FunctionalInterface注释,编译器都会将符合函数接口定义的任何接口视为函数接口。

源码如下:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}

需要注意的是:函数式接口只有一个抽象方法,接口声明覆盖 java.lang.Object的抽象方法,不会进行抽象方法计数。这对后面介绍几个常用的接口很有用!!

二、Supplier<T>

        先看一下源码:

/**
  * 表示结果的供应者。
  * 没有要求每次调用供应者时都返回新的或不同的结果。
  */
@FunctionalInterface
public interface Supplier<T> {

    /**
     * Gets a result.
     */
    T get();
}

        Supplier<T> 接口源码中只有个get()方法。每次调用get()方法,就会调用构造方法,获取对象实例。

        示例:每次调用get()方法都返回一个整数:

        Supplier<Integer> supplier = new Supplier<Integer>() {
            @Override
            public Integer get() {
                return new Random().nextInt();
            }
        };
        System.out.println(supplier.get());

        结合Lambda表达式应用:

    List<Integer> integers = makeList(10, () -> (int) (Math.random() * 10));
    integers.forEach(System.out::println);
 
    private List<Integer> makeList(int num, Supplier<Integer> supplier){
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < num; i++) {
            list.add(supplier.get());
        }
        return list;
    }

        结合方法引用应用:

Supplier<Double> supplier1 = Math::random;
System.out.println(supplier1.get());

三、Consumer<T>

Java源码:

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

        Consumer<T>表示接受单个输入参数而不返回结果的操作。java.util.function.Consumer 接口则正好与上面的Supplier<T> 接口相反,它不是生产一个数据,而是消费一个数据, 其数据类型由泛型决定。

该类有两个方法

  • void accept(T t);【抽象方法】

        该方法对给定的参数执行此操作。

  • default Consumer<T> andThen(Consumer<? super T> after)【默认实现方法】

        返回一个组合的Consumer,该Consumer依次执行此操作和after操作。如果执行任何一个操作都会引发异常,则会将异常中继到组合操作的调用方。如果执行此操作会引发异常,则不会执行after操作。

1、抽象方法accept的使用

该方法消费一个指定泛型的数据:

import java.util.function.Consumer;
 
public class Demo01Consumer {
    public static void main(String[] args) {
        consumerString(s -> System.out.println(s));
    }
 
    private static void consumerString(Consumer<String> function) {
        function.accept("Hello");
    }
}

运行程序,控制台输出:Hello

2、默认方法andThen的使用

        如果一个方法的参数和返回值全都是 Consumer 类型,那么就可以实现效果:消费数据的时候,首先做一个操作, 然后再做一个操作,实现组合。而这个方法就是 Consumer 接口中的default方法 andThen 。

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

提示:java.util.Objects 的 requireNonNull 静态方法将会在参数为null时主动抛出 NullPointerException 异常。这省去了重复编写if语句和抛出空指针异常的麻烦。

        要想实现组合,需要两个或多个Lambda表达式即可,而 andThen 的语义正是“一步接一步”操作。例如两个步骤组合的情况:

import java.util.function.Consumer;
 
public class Demo02Consumer {
    public static void main(String[] args) {
        consumerString(
                // toUpperCase()方法,将字符串转换为大写
                s -> System.out.println(s.toUpperCase()),
                // toLowerCase()方法,将字符串转换为小写
                s -> System.out.println(s.toLowerCase())
        );
    }
 
    private static void consumerString(Consumer<String> one, Consumer<String> two) {
        one.andThen(two).accept("Hello");
    }
}

        运行结果将会首先打印完全大写的HELLO,然后打印完全小写的hello。当然,通过链式写法可以实现更多步骤的组合。

四、Function<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;
    }
}

Function<T,R>接口的作用的是用来表现一个参数类型为T、返回值类型为R的函数(方法)。

Function 接口是一个功能型接口,是一个转换数据的作用。接收一个T参数,返回一个R结果

Function 接口实现 apply 方法来做转换。

一个简单的示例:

Function<String, Boolean> function = p -> p.length() == 5;
Stream<Boolean> stream = stringList().stream().map(function);

默认方法1:<V> Function<V, R> compose(Function<? super V, ? extends T> before)

返回一个组合函数,该函数首先将before函数应用于其输入,然后将此函数应用于结果。如果对任意一个函数的求值引发异常,则会将异常中继到组合函数的调用方。

默认方法2:<V> Function<T, V> andThen(Function<? super R, ? extends V> after)

返回一个组合函数,该函数首先将此函数应用于其输入,然后将after函数应用于结果。如果对任意一个函数的求值引发异常,则会将异常中继到组合函数的调用方。

静态方法:static <T> Function<T, T> identity()

返回一个始终返回其输入参数的函数。

五、Predicate<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);
    }
}

Predicate<T>常用的四个方法:
boolean test(T t):对给定的参数进行判断(判断逻辑由Lambda表达式实现),返回一个布尔值
default Predicate<T> negate():返回一个逻辑的否定,对应逻辑非
default Predicate<T> and(Predicate other):返回一个组合判断,对应短路与
default Predicate<T> or(Predicate other):返回一个组合判断,对应短路或
Predicate<T>接口常用于判断参数是否满足指定的条件

最常见的应用是在集合Stream流过滤条件中使用:

import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
 
 
public class LambdaStudy
{
    public static void main(String[] args) {
       
        //初始化list集合
        List<String> list = new ArrayList<String>();
        list.add("测试数据1");
        list.add("测试数据2");
        list.add("测试数据3");
        list.add("测试数据12");
        
        //使用λ表达式遍历集合
        list.forEach(s -> System.out.println(s));
        
        //结合Predicate使用和过滤条件筛选元素
        Predicate<String> contain1 = n -> n.contains("1");
        Predicate<String> contain2 = n -> n.contains("2");
        
        //根据条件遍历集合
        list.stream().filter(contain1).forEach(n -> System.out.println(n));
        list.stream().filter(s -> contain1.test(s)).forEach(s -> System.out.println(s));
        list.stream().filter(contain1.and(contain2)).forEach(n -> System.out.println(n));
        list.stream().filter(contain1.or(contain2)).forEach(n -> System.out.println(n));
        
        //将过滤后的元素重新放到一个集合中
        List<String> newList = list.stream().filter(contain1.and(contain2)).collect(Collectors.toList());
        
        newList.forEach(s -> System.out.println(s));
 
    }
}

Java从入门到精通十六(函数式接口编程) 这其实就是一种函数式编程,体现了一种逻辑思维。函数式编程的一个非常方便的体现就是lambda表达式。所以函数式接口非常适合配合lambda去使用。 阅读详情

相关推荐

Java中常用的函数式接口编程

Java 8引入了函数式接口,提供了一种方便的方式来使用Lambda表达式和方法引用。这些是Java中常用的函数式接口,它们为函数式编程提供了强大的支持。上述示例中,我们使用Predicate接口实现了一个判断数字是否为偶数的操作,并将其应用于一个数字列表。上述示例中,我们使用Function接口实现了一个获取字符串长度的操作,并将其应用于一个字符串。上述示例中,我们使用Consumer接口实现了一个打印语言的操作,然后通过。上述示例中,我们使用Supplier接口实现了一个生成随机数的操作。

ScriptCharm的博客 136

Java函数式编程

函数式接口:有且仅有一个抽象方法的接口Java 中的函数式编程体现就是 Lambda 表达式,所以函数式接口就是可以适用于 Lambda 使用的接口只有确保接口中有且仅有一个抽象方法,Java 中的 Lambda 才能顺利地进行推导如何检测一个接口是不是函数式接口呢?放在接口定义的上方:如果接口是函数式接口,编译通过;如果不是,编译失败。

qq_49487356的博客 9414

对数周期天线hfss建模_Ansoft HFSS 在设计对数周期天线时的仿真方法-HFSS教程

AnsoftHFSS在设计对数周期天线时的仿真方法文章来源: ANSYS 2011中国用户大会优秀论文 录入: mweda.com 点击数:【摘要】 本文通过 ANSOFT HFSS 设计了一个对数周期天线,在仿真分析时,发现随着求解频率的不同,天线的求解结果差别较大,求解误差较大。通过在 HFSS 中尝试不同的求解设置方法, 最终通过将天线模型剖分网格最大长度限定在 1/50λ的...

weixin_42186728的博客 2099

Java学习——函数式编程

Java学习笔记——函数式编程

weixin_44456914的博客 3860

ArcGIS基础:点要素分割线要素和提取线要素的交点

第一个实验:【点要素分割线要素】看下原始数据:下图所示,2个红点和一条绿线,用2个点去分割这条线。 找到【数据管理工具】,在找到【要素】,再找到【在点处分割线】,如下图所示。 输入线、点要素,然后在【搜索半径】里输入5米,查看一下结果。 查看结果发现,线段被分割了2段,我们查看一下原因。 发现第2个点与线有一段距离,肯定是大于5米的,所以分割没有成功。可以量测一下距离,重新输入搜索半径。 我们把搜索半径改为200米,勘察结果,被点分割了3段。 接下来使用另外一个工具【在折点处分割线】,如下所示。

yuanYW7556的博客 1万+

Unity游戏开发实战:用Flow Field实现RTS百人军团流畅寻路(附完整代码)

本文深入探讨了在Unity中利用流场寻路技术解决RTS游戏大规模单位移动性能瓶颈的实战方案。通过解析从Dijkstra算法生成成本场、积分场到最终向量场的核心原理,并结合分块、缓存及与DOTS/ECS架构集成的优化策略,实现了百人军团的流畅群体寻路。文章提供了完整的代码示例,助力开发者构建高性能的RTS寻路系统。

weixin_28363123的博客 587

《Java 基础篇》之函数式接口

有且仅有一个抽象方法的接口。Java中的函数式编程体现就是Lambda表达式。所以函数式接口即可以适用于Lambda使用的接口。如何检测一个接口是不是函数式接口?放在接口定义的上方:如果接口是函数式接口,编译通过;如果不是,编译失败。");i.show();注意:自定义函数式接口时,@FunctionalInterface是可选的,就算不写这个注解,只要保证满足函数式接口定义的条件,也照样是函数式接口。

huangtenglong的博客 8615

Win11+VSCode+TeXLive:学术党必备的LaTeX环境配置避坑指南(2024最新版)

本文详细介绍了如何在Windows 11系统下,通过VSCode编辑器与TeXLive发行版配置高效的LaTeX学术写作环境。针对国内用户常见的镜像下载慢、插件配置复杂等问题,提供了优化方案和避坑指南,帮助科研人员和学生快速搭建流畅的学术写作工作流。

plum99的博客 619

Java函数式接口(函数式编程、常用的函数式接口)

*@FunctionalInterface注解:作用:是检测接口是否是一个函数式接口注意:如果接口中没有抽象方法或者抽象方法的个数多余1个,该注解则会报错* *///定义一个抽象方法// 同样public abstract可以省略。。由于接口当中的抽象方法//定义一个抽象方法。

Best_Basic的博客 2228

vcs 覆盖率收集1——三种覆盖率类型、covergroup、bins、数据采样、覆盖率选项

介绍各种覆盖率,以及如何编写覆盖率收集的代码

qq_42135020的博客 1万+

域控制器开发避坑实录:从硬件设计到软件集成的5个关键挑战

本文深入剖析了域控制器开发中的5大关键挑战,从硬件选型到软件集成,涵盖智能驾驶芯片选择、实时性优化、AUTOSAR架构适配等核心问题。通过实战案例和数据对比,为工程师提供避坑指南,助力提升开发效率和系统可靠性。

weixin_29258297的博客 395

Java基础-10(函数式接口,函数式编程,常用函数式接口,Stream流)

54.函数式接口 概念 函数式接口在Java中是指:有且仅有一个抽象方法的接口。 函数式接口,即适用于函数式编程场景的接口。而Java中的函数式编程体现就是Lambda,所以函数式接口就是可 以适用于Lambda使用的接口。只有确保接口中有且仅有一个抽象方法,Java中的Lambda才能顺利地进行推导。 备注:“语法糖”是指使用更加方便,但是原理不变的代码语法。例如在遍历集合时使用的for-each语法,其实 底层的实现原理仍然是迭代器,这便是“语法糖”。从应用层面来讲,Java中的Lambda可以被

q172395505的博客 348

linux基线检查、基线加固、安全漏扫、系统漏洞、centos7、文尾部附脚本

等保三级-CentOS Linux 7合规基线检查 风险分类:系统-等保三级-CentOS Linux 7合规基线检查 检测项说明: CentOS Linux 7合规基线检查,对标中国等保2.0第三级等级保护基本要求部分检查项目,仅供参考 检查项目 : 应对登录的用户进行身份标识和鉴别,身份标识具有唯一性,身份鉴别信息具有复杂度要求并定期更换 加固建议: 1、执行`cat /etc/shadow | awk -F: '($2 == "" ) { print $1}' `, 查看空密码账户并处理; 2、

swindy博客 5622

Java常用函数式编程接口

一、函数式编程接口 Java中的函数式接口一共有四种,其都被注解@FunctionalInterface注释,表明这是一个函数式接口: 消费型接口(Consumer<T>):接口方法void accept(T t),参数T,无返回值; 供给型接口(Supplier<T>):接口方法T get(),返回T类型返回值; 函数型接口(Function<T, R>):接口方法R apply(T t),入参为T类型,返回R类型返回值; 断言型接口(Predicate&lt

Armyyyyy丶的博客 818

八、ILI2511 初版调试

8.1 TP成品过程 TP厂在制造TP过程中会经过FPC、FOG和Model三个阶段。 FPC: 将IC做在FPC上面; FOG: 将FPC与sensor 绑定; Model:FOG阶段后,贴上CG(cover glass)。 经过上面三个阶段后,将会拿到没有烧录固件的TP模组。这个时候触摸TP,并不能上报触摸数据,需要对TP模组烧录固件(执行程序)后才会有TP有触摸数据。 8.2 源码编译固件与工具生成固件 我们可以通过以下两种方式获得固件 1)由奕力原厂直接通过源码,进行编...

qq_34343637的博客 3689

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Java语言基础Day28(函数式接口、函数式编程、常用的函数式接口)

今日内容一、函数式接口1.函数式接口的概念&函数式接口的定义 一、函数式接口 1.函数式接口的概念&函数式接口的定义

MysEaiZYH的博客 200

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

JAVA学习12——函数式接口、函数式编程、常用函数式接口(Supplier、Function、Predicate、Consumer)

1.函数式结构概述 函数式接口在java中指的是,有且仅有一个抽象方法的接口(但可以有其他静态方法、默认方法、私有方法等)。函数式接口适用于函数式编程场景的接口,Java中就是Lambda。 tips:(1)”语法糖“,指使用更加方便,原理不变的代码语法;(2)@Override注解的作用,是检查方法是否为重写方法,是则编译成功,否则编译失败。 (3)同样,可以在函数式接口前,添加一个@Functional 函数式接口的格式 修饰符 interface 接口名称 { public abstract 返回值

weixin_46185085的博客 287

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

java 8 lambda 函数_Java8函数式编程(一):Lambda表达式类型与常用函数接口

[TOC]1 前言最近在看一些开源项目的源码,函数式编程风格的代码无处不在,所以得要好好学一下了。2 Lambda表达式类型无参数:Runnable noArguments = () -> System.out.println("Hello World!");noArguments.run();一个参数:UnaryOperator oneArgument = x -> !x;Syste...

weixin_35645652的博客 218

JAVA 1.8 特性功能(函数式接口、方法引用、函数式编程、常用函数式接口)

函数式接口一、概念 函数式接口在Java中是指:有且仅有一个抽象方法的接口。 函数式接口,即适用于函数式编程场景的接口。而Java中的函数式编程体现就是Lambda,所以函数式接口就是可以适用于Lambda使用的接口。只有确保接口中有且仅有一个抽象方法,Java中的Lambda才能顺利地进行推导。 二、格式 只要确保接口中有且仅有一个抽象方法即可: 说明:函数式接口要求只有一个抽象方法。但是还可...

weixin_39559301的博客 319

java socket接口文档_Java进阶 - 网络编程、Socket、函数式接口、常用的函数式接口...

1.网络通信协议网络通信协议:通信协议是对计算机必须遵守的规则,只有遵守这些规则,计算机之间才能进行通信。这就好比在道路中行驶的汽车一定要遵守交通规则一样,协议中对数据的传输格式、传输速率、传输步骤等做了统一规定,通信双方必须同时遵守,最终完成数据交换。TCP/IP协议: 传输控制协议/因特网互联协议( Transmission Control Protocol/Internet Protocol...

weixin_42113552的博客 459

java8自带常用的函数式接口 和 stream api流式编程

java8自带常用的函数式接口 Predicate boolean test(T t) 传入一个参数返回boolean值 Consumer void accept(T t) 传入一个参数,无返回值 Function<T,R> R apply(T t) 传入一个参数,返回另一个类型 准备数据 //计算机俱乐部 private static List<Student> computerClub = Arrays.asList( new Student

Handsome_BoyIT的博客 214

Java函数式接口

函数式接口与JDK中4大函数式接口的使用

qq_43770865的博客 870

Java8新特性——函数式接口

【前言】 项目中物流模块用到了Stream,Stream和函数式接口又紧紧相关。 【主体】 (一)函数式接口 (1)概念 有且仅有一个抽象方法 (2)格式 修饰符 interface 接口名称{ public abstract 返回值类型 方法名称(可选参数信息); //其他非抽象方法内容 } 其中的public abstract是可以省略的。 (3)@FunctionalInterface注解 一旦使用该...

在这个充满危险的乱世之中,只有学会烤鸡才能顽强的活下去。 623

[AIGC] Java 函数式编程

在本篇文章中,我们介绍了Java函数式编程以及常用的函数式接口。Lambda表达式和函数式接口是函数式编程的两个重要概念,可以让代码更加简洁和灵活。Java提供了一些常用的函数式接口,如Function、Consumer、Predicate、Supplier等,可以通过方法引用更加简洁地实现函数式编程。使用函数式编程,可以让你的代码更加优雅,简洁。

2301_79528833的博客 333

02_12_Java语音进阶||day12【】_函数式接口、函数式编程、常用函数式接口(Supplier、Consumer、Predicate、Function)

第一章 函数式接口 1.1 函数式接口的概念&函数式接口的定义 函数式接口在Java中是指:有且仅有一个抽象方法的接口。 语法糖是指:使用更加方便,但是原理不变的代码语法。 例:for-each就是迭代器的语法糖。 从应用层来讲:Lambda可以当做匿名内部类的语法糖 但是二者原理是不同的。 匿名内部类会生成.class文件($命名),但是Lambda不会 所以Lambda效率高 ...

qq_40572023的博客 261

Java---函数式接口

对于刚刚定义好的函数式接口,典型使用场景就是作为方法的参数://调用show方法,方法的参数是一个接口,所以可以传递接口的实现类对象//调用show方法,方法的参数是一个接口,所以我们可以传递接口的匿名内部类@OverrideSystem.out.println(“使用匿名内部类重写接口中的抽象方法”);});//调用show方法,方法的参数是一个函数式接口,所以我们可以用Lambda表达式。

2501_90404736的博客 621
上一篇: Java8 Optional类型
下一篇: Effective Java笔记(13)谨慎地覆盖 clone
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值