Java基础学习之函数式编程Comsumer接口(JDK8)

2023-11-10

前言

        从毕业到现在正好三年,高难度的项目做了不少,但是基础这个东西一段时间不接触就会忘得一干二净。话不多说,开始今天的学习!

1. Consumer接口

      接触过“消费者”,“生产者”模式的同学,肯定对这个单词不陌生,在java8函数式编程和lambda表达式加入之后,这个接口直接深入的影响了之前的集合,JAVA8中Iterable的源代码如下:

package java.lang;

import java.util.Iterator;
import java.util.Objects;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Consumer;

public interface Iterable<T> {
    Iterator<T> iterator();

    default void forEach(Consumer<? super T> var1) {
        Objects.requireNonNull(var1);
        Iterator var2 = this.iterator();

        while(var2.hasNext()) {
            Object var3 = var2.next();
            var1.accept(var3);
        }

    }

    default Spliterator<T> spliterator() {
        return Spliterators.spliteratorUnknownSize(this.iterator(), 0);
    }
}

顺便提到的是 default这个接口的默认方法是一起在JAVA8中加入的。

相信大家在处理集合时或多或少都用到了“forEach”这个遍历方法,不得不说这个方法真的是很好用。

package mytest;


import java.util.ArrayList;

public class StringBuilderTest {
    public static void main(String[] args) {
        //准备一个list
        ArrayList<Integer> integers = new ArrayList<>();
        for(int i = 0 ;i<=10;i++){
            integers.add(i);
        }
        //java8之前的遍历
        for(Integer i :integers){
            System.out.println(i);
        }
        //java8的遍历
        integers.forEach(System.out::println);
        integers.forEach(integer -> System.out.println(integer));
    }

}

jdk8中使用了::的用法。就是把方法当做参数传到stream内部,使stream的每个元素都传入到该方法里面执行一下,双冒号运算就是Java中的[方法引用],[方法引用]的格式是:

  类名::方法名 

注意此处没有()

一般的lambda表达式就是 -> 符号,跟c++中的调用类中的参数一样。

这样的代码看起来就很整齐,而且在可读性方面也很不错。但是我们今天的主角是Consumer,接下来我换一种写法:

package mytest;


import java.util.ArrayList;
import java.util.function.Consumer;

public class StringBuilderTest {
    public static void main(String[] args) {
        //准备一个list
        ArrayList<Integer> integers = new ArrayList<>();
        for(int i = 0 ;i<=10;i++){
            integers.add(i);
        }
        //java8之前的遍历
        for(Integer i :integers){
            System.out.println(i);
        }
        //java8的遍历
        integers.forEach(System.out::println);
        //Consumer
        Consumer<Integer>  integerConsumer = new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) {
                System.out.println(integer);
            }
        };
        integers.forEach(integerConsumer);
    }

}

唉?这不是我们非常熟悉的匿名内部类吗~

没错,lambda表达式将匿名内部类的创建简化成了一个符号。接下来就该隆重的请上Consumer的源码了:

package java.util.function;

import java.util.Objects;

@FunctionalInterface
public interface Consumer<T> {
    void accept(T var1);

    default Consumer<T> andThen(Consumer<? super T> var1) {
        Objects.requireNonNull(var1);
        return (var2) -> {
            this.accept(var2);
            var1.accept(var2);
        };
    }
}

首先这个接口呢有一个@FunctionalInterface注解,Java 8为函数式接口引入了一个新注解@FunctionalInterface,主要用于编译级错误检查,加上该注解,当你写的接口不符合函数式接口定义的时候,编译器会报错。

所谓的函数式接口,当然首先是一个接口,然后就是在这个接口里面只能有一个抽象方法

这种类型的接口也称为SAM接口,即Single Abstract Method interfaces。

当我们用lambda表达式来时限Consumer接口时,其实就是在实现接口中的这个唯一抽象方法,由于Consumer设计出来是处理数据,并且是不带返回值的,所以在处理打印日志,数据库操作的时候会比较常用到。所以方法里面还有一个andThen方法,顾名思义,就是可以顺序来执行多个Consumer,如下:

package mytest;


import java.util.ArrayList;
import java.util.function.Consumer;

public class StringBuilderTest {
    public static void main(String[] args) {
        //准备一个list
        ArrayList<Integer> integers = new ArrayList<>();
        for(int i = 0 ;i<=10;i++){
            integers.add(i);
        }
        //java8之前的遍历
//        for(Integer i :integers){
//            System.out.println(i);
//        }
        //java8的遍历
//        integers.forEach(System.out::println);
        //Consumer
        Consumer<Integer>  integerConsumer = new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) {
                System.out.println(integer);
            }
        };
        integerConsumer = integerConsumer.andThen(integerConsumer).andThen(integerConsumer);
        integers.forEach(integerConsumer);
    }

}

我做了一个打印X3的效果,结果如下:

0
0
0
1
1
1
2
2
2
3
3
3
4
4
4
5
5
5
6
6
6
7
7
7
8
8
8
9
9
9
10
10
10

所以Consumer作为一个不返回结果的流处理接口,这方面还是很给力的。

作为函数式编程的第一个接口,特点就是“有入参,无出参”。

下一章我们继续学习Predicate接口

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java基础学习之函数式编程Comsumer接口(JDK8) 的相关文章

  • 策略模式还是命令模式?

    假设我有一个金融交易列表 我需要针对这些交易执行一系列验证规则 一个例子是我有一笔购买产品的交易 但是首先我需要验证交易中的帐户是否有足够的可用资金 产品没有售完等 由于这些规则 交易将是标记为拒绝 并应指定错误代码 当然 我正在考虑用一个
  • 将构造函数作为参数传递给方法

    我是java新手 开始研究构造函数 我看到一些构造函数作为参数传递给方法的示例 请告诉我当构造函数作为参数传递给方法时会发生什么 或者建议我一些链接 我可以在其中获得有关使用构造函数的足够知识 根据您需要传递构造函数的目的 您可以考虑传递供
  • 在 Java 正则表达式中获取多个模式的重叠匹配

    我有同样的问题这个链接 https stackoverflow com questions 18751486 matching one string multiple times using regex in java 但有多种模式 我的正
  • 在 jTextfield 中禁用“粘贴”

    我有一个用 Swing awt 编写的应用程序 我想阻止用户将值粘贴到文本字段中 有没有办法在不使用动作监听器的情况下做到这一点 您可以使用 null 参数调用 setTransferHandler 如下所示 textComponent s
  • 在哪里保存选项值、重要文件的路径等[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我正在创建一个程序 需要设置一些选项值以及图像文件的一些路径 SQLite 数据库的路径 有关各种按钮上文本的一些信息 有关要使用哪个数据库的信
  • 这个等待通知线程语义的真正目的是什么?

    我刚刚遇到一些代码 它使用等待通知构造通过其其他成员方法与类中定义的线程进行通信 有趣的是 获取锁后 同步范围内的所有线程都会在同一锁上进行定时等待 请参见下面的代码片段 随后 在非同步作用域中 线程执行其关键函数 即 做一些有用的事情1
  • 如何在 HandlerInterceptorAdapter 中添加 HttpServletRequest 标头?

    我正在尝试将授权标头添加到我的请求中 作为我们切换环境时的临时解决方法 我试图在扩展 HandlerInterceptorAdapter 的拦截器中处理它 我使用 MutableHttpServletRequest 类制作here http
  • Emacs Lisp 可以将 lambda 形式分配给像Scheme 这样的变量吗?

    在研究 Emacs Lisp 的符号单元时 我发现像这样的示例函数 defun a rest x x 我可以打电话 symbol function a 返回 lambda rest x x 如果我愿意的话我可以使用它 gt lambda r
  • 如何在 JPA 和 Hibernate 中将数据库生成的列值定义为只读字段?

    使用 MariaDB 10 2 可以定义日期时间的默认值 例如创建和最后修改 我应该如何将此列作为只读字段访问 因为这个值应该只在数据库的控制之下 并且不应该从代码中修改 但我想在代码中读取这个属性 这很简单 只需设置insertable
  • 拆分/标记化/扫描字符串并注意引号

    Java中是否有默认 简单的方法来分割字符串 但要注意引号或其他符号 例如 给定以下文本 There s a man that live next door in my neighborhood and he gets me down Ob
  • 在 java 中运行外部应用程序但不要等待它完成

    我正在用java编写一个应用程序 允许我运行其他应用程序 为此 我使用了 Process 类对象 但当我这样做时 应用程序会等待进程结束 然后再退出 有没有办法在 Java 中运行外部应用程序 但不等待它完成 public static v
  • Java 中 JButton 的击键/热键

    最初我使用 JMenu 并建立热键以使用加速器工作 它运行得很好 现在我想在 JButton 中实现相同的行为 但我陷入困境 这是我编写的代码 请分享您的想法 以便我可以走上正确的道路 import javax swing import j
  • 使用单独的线程在java中读取和写入文件

    我创建了两个线程并修改了 run 函数 以便一个线程读取一行 另一个线程将同一行写入新文件 这种情况会发生直到整个文件被复制为止 我遇到的问题是 即使我使用变量来控制线程一一执行 但线程的执行仍然不均匀 即一个线程执行多次 然后控制权转移
  • javax.media.jai 类的公共下载?

    这是一个非常简单的问题 我一直在寻找可以下载 javax media jai 库的地方 我找到了 jai imageio 库 但是我发现的所有其他 jai 内容要么已经过时 2008 年及之前 然后我遇到了登录屏幕 是否有 javax me
  • 使用 PC/SC 读卡器验证 Ultralight EV1

    我在尝试使用 Java 中的 PC SC 读卡器 特别是 ACR1222L 验证 Ultralight EV1 卡时遇到问题 我能够使用 ISO 14443 3 标签的相应 APDU 在不受保护的标签上进行写入和读取 但是 我找不到运行 P
  • 如何从 JavaFX 中的另一个控制器类访问 UI 元素?

    我有一个使用 NetBeans 8 编写的 JavaFX Java 8 应用程序 没有SceneBuilder 我的应用程序有一个主窗口 该窗口有自己的 FXML 文件 primary fxml 和自己的控制器类 FXMLPrimaryCo
  • java.lang.IllegalStateException - 提交响应后无法创建会话

    我在我的项目中使用 JSF PrimeFaces 我为此准备了一个Maven项目 当我编译项目并加载主页后 我收到以下异常 java lang IllegalStateException Cannot create a session af
  • spring data jpa复合键重复键记录插入导致更新

    我有一个具有复合键的实体 我试图通过使用 spring data jpa 存储库到 mysql 数据库来持久化它 如下所示 Embeddable public class MobileVerificationKey implements S
  • 受信任的 1.5 小程序可以执行系统命令吗?

    如果是的话 这个能力有什么限制吗 具体来说 我需要以 Mac OSX 为目标 我以前用过这个在 Windows 系统上启动东西 但从未在 Mac 上尝试过 public void launchScript String args Strin
  • 为什么java.lang.Cloneable不重写java.lang.Object中的clone()方法?

    Java 规范java lang Cloneable接口将自身定义为表示扩展它的任何对象也实现了clone 休眠的方法java lang Object 具体来说 它说 一个类实现了Cloneable接口来指示java lang Object

随机推荐

  • el-table实现指定列合并

    table传入span method方法可以实现合并行或列 方法的参数是一个对象 里面包含当前行row 当前列column 当前行号rowIndex 当前列号columnIndex四个属性 该函数可以返回一个包含两个元素的数组 第一个元素代
  • Datax-HdfsWriter如何实现支持decimal类型数据写入

    一 问题背景 之前在做Datax数据同步时 发现源端binary decimal等类型的数据无法写入hive字段 看了一下官网文档 DataX HdfsWriter 插件文档 是1 2年前的 当初看过部分源码其实底层hadoop是支持这些类
  • 摸鱼周报年终总结

    今年摸鱼周报的发展超出预期的顺利 离不开各位编辑小伙伴的帮助和读者的支持 非常感谢大家 到了年后最后一周就休刊一期发一个总结吧 今年有很多有趣的事值得再回顾下 编程学习资料点击免费领取 梦开始的地方 最开始的想法 开始写摸鱼周报是因为社群建
  • 华为OD机试 - 字符串变换最小字符串 - (Java 2022Q4 100分)

    目录 一 题目描述 二 输入描述 三 输出描述 四 解题思路 五 Java算法源码 六 效果展示 1 输入 2 输出 华为OD机试 2023B卷题库疯狂收录中 刷题点这里 一 题目描述 给定一个字符串s 最多只能进行一次变换 返回变换后能得
  • 数据分析和可视化必备的几大软件,你用过几个?

    本文主要是面向数据分析初学者 因此分享的基本是一些免编程的可视化工具 详细介绍了7款工具 推荐大家使用 主要是让初学数据分析的朋友知道可视化工具大概有哪些 流行的有哪些 Power BI Power BI是微软开发的商业分析工具 用户可以在
  • 单片机与电脑接口(TTL与RS232电平模拟转换)电路及工作原理分析

    RS232接口概述 RS232接口又称DB9接口 是现在主流的串行通信接口之一 由于RS232接口标准出现较早 难免有不足之处 主要有以下四点 1 接口的信号电平值较高 易损坏接口电路的芯片 又因为与TTL电平不兼容故需使用电平转换电路方能
  • Hibernate缓存机制

    原文地址 http www iteye com topic 249465 缓存是位于应用程序与物理数据源之间 用于临时存放复制数据的内存区域 目的是为了减少应用程序对物理数据源访问的次数 从而提高应用程序的运行性能 Hibernate在查询
  • Pandas必会的方法汇总,用Python做数据分析更加如鱼得水!(附代码)

    用Python做数据分析光是掌握numpy和matplotlib可不够 Pandas是必须要掌握的一个重点 numpy虽然能够帮我们处理处理数值型数据 但是这还不够 很多时候 我们的数据除了数值之外 还有字符串 还有时间序列等 今天来分享一
  • 2022快速计算机视觉EI国际会议汇总

    本文不包含刚举办两三年的国内水会 主要收录了一些或许比较容易中且快速出结果的真正意义上的国际会议 可能存在编辑错误 最终以各会议官网为准 随缘更新 Abbr Name Submission Deadline Notification of
  • 整数在内存中如何存储

    整数在内存中的存储 在计算机内存中 整数一律采用补码的形式来存储 这意味着 当读取整数时还要采用逆向的转换 也就是将补码转换为原码 将补码转换为原码也很简单 先减去 1 再将数值位取反即可 我们先来解以下几个概念 原码 将一个整数转换成二进
  • 刷脸签到系统的设计与实现python+flask+mysql

    刷脸签到系统的设计与实现 语言 工具 html css ajax pyhotn Flask框架 bootstrap框架 SQLAlchemy mysql数据库 介绍 利用Python语言 Flask框架 Dlib库 MySQL数据库等工具设
  • Java线程:线程的调度-守护线程

    本文转载至 http lavasoft blog 51cto com 62575 221845 Java线程 线程的调度 守护线程 守护线程与普通线程写法上基本么啥区别 调用线程对象的方法setDaemon true 则可以将其设置为守护线
  • 贵阳市职称计算机报名时间,贵州贵阳市2013年职称计算机考试报名时间

    一 考试科目 科 目备 注 1中文Windows XP操作系统 2Word 2003中文字处理 3Excel 2003中文电子表格考生任选其一 金山表格2005 4PowerPoint 2003中文演示文稿考生任选其一 金山演示2005 5
  • hping 详解_hping3使用

    简介 hping3是一款免费的数据包生成器和分析器 可用于安全审计 防火墙规则测试 网络测试 端口扫描 性能测试 压力测试 DOS 几乎可以发送任意类型的TCP IP数据包 功能强大但是每次只能向一个IP地址发送数据包 还能够在两个相互包含
  • spring应用从多个properties文件中加载数据的问题

  • arch linux 文档下载_CASTEP的Linux 安装

    CASTEP http www castep org 是一款电子结构软件 可以计算Kohn Sham框架下的平面波DFT 能够完成VASP能够完成的大部分计算 相比于VASP有几个优势 能够完成基本所有VASP能实现的功能和一些VASP不能
  • golang中的随机数rand

    1 math rand 随机数从资源生成 包水平的函数都使用的默认的公共资源 该资源会在程序每次运行时都产生确定的序列 如果需要每次运行产生不同的序列 应使用Seed函数进行初始化 默认资源可以安全的用于多go程并发 关于种子seed 程序
  • nginx实现路由重定向功能 避免服务器出现 404 Not Found

    首先 到服务器上 vue react等项目路由的重定向已解决不了带后缀的访问 这个重定向需要 nginx 来实现 我们先执行 scp r 用户名 如果没设置过就是root 服务器公网地址 etc nginx nginx conf E 拷贝地
  • Java基础最新教程-小白到大神,从api层面到底层原理解抛

    JavaSe JDK JRE JVM是什么 JDK Java Development Kit JRE Java Runtime Environment JVM Java Virtual Machine Java跨平台核心是使用Jvm 在不同
  • Java基础学习之函数式编程Comsumer接口(JDK8)

    前言 从毕业到现在正好三年 高难度的项目做了不少 但是基础这个东西一段时间不接触就会忘得一干二净 话不多说 开始今天的学习 1 Consumer接口 接触过 消费者 生产者 模式的同学 肯定对这个单词不陌生 在java8函数式编程和lamb