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) 的相关文章

  • Grails 3.x bootRun 失败

    我正在尝试在 grails 3 1 11 中运行一个项目 但出现错误 失败 构建失败并出现异常 什么地方出了错 任务 bootRun 执行失败 进程 命令 C Program Files Java jdk1 8 0 111 bin java
  • 在 Java 中连接和使用 Cassandra

    我已经阅读了一些关于 Cassandra 是什么以及它可以做什么的教程 但我的问题是如何在 Java 中与 Cassandra 交互 教程会很好 如果可能的话 有人可以告诉我是否应该使用 Thrift 还是 Hector 哪一个更好以及为什
  • 为什么 i++ 不是原子的?

    Why is i Java 中不是原子的 为了更深入地了解 Java 我尝试计算线程中循环的执行频率 所以我用了一个 private static int total 0 在主课中 我有两个线程 主题 1 打印System out prin
  • Java EE:如何获取我的应用程序的 URL?

    在 Java EE 中 如何动态检索应用程序的完整 URL 例如 如果 URL 是 localhost 8080 myapplication 我想要一个可以简单地将其作为字符串或其他形式返回给我的方法 我正在运行 GlassFish 作为应
  • Final字段的线程安全

    假设我有一个 JavaBeanUser这是从另一个线程更新的 如下所示 public class A private final User user public A User user this user user public void
  • Android:捕获的图像未显示在图库中(媒体扫描仪意图不起作用)

    我遇到以下问题 我正在开发一个应用程序 用户可以在其中拍照 附加到帖子中 并将图片保存到外部存储中 我希望这张照片也显示在图片库中 并且我正在使用媒体扫描仪意图 但它似乎不起作用 我在编写代码时遵循官方的Android开发人员指南 所以我不
  • 列出jshell中所有活动的方法

    是否有任何命令可以打印当前 jshell 会话中所有新创建的方法 类似的东西 list但仅适用于方法 您正在寻找命令 methods all 它会打印所有方法 包括启动 JShell 时添加的方法 以及失败 被覆盖或删除的方法 对于您声明的
  • 反射找不到对象子类型

    我试图通过使用反射来获取包中的所有类 当我使用具体类的代码 本例中为 A 时 它可以工作并打印子类信息 B 扩展 A 因此它打印 B 信息 但是当我将它与对象类一起使用时 它不起作用 我该如何修复它 这段代码的工作原理 Reflection
  • 操作错误不会显示在 JSP 上

    我尝试在 Action 类中添加操作错误并将其打印在 JSP 页面上 当发生异常时 它将进入 catch 块并在控制台中打印 插入异常时出错 请联系管理员 在 catch 块中 我添加了它addActionError 我尝试在jsp页面中打
  • 无法解析插件 Java Spring

    我正在使用 IntelliJ IDEA 并且我尝试通过 maven 安装依赖项 但它给了我这些错误 Cannot resolve plugin org apache maven plugins maven clean plugin 3 0
  • 从 127.0.0.1 到 2130706433,然后再返回

    使用标准 Java 库 从 IPV4 地址的点分字符串表示形式获取的最快方法是什么 127 0 0 1 到等效的整数表示 2130706433 相应地 反转所述操作的最快方法是什么 从整数开始2130706433到字符串表示形式 127 0
  • 为什么HashMap不能保证map的顺序随着时间的推移保持不变

    我在这里阅读有关 Hashmap 和 Hashtable 之间的区别 http javarevisited blogspot sg 2010 10 difference Between hashmap and html http javar
  • JRE 系统库 [WebSphere v6.1 JRE](未绑定)

    将项目导入 Eclipse 后 我的构建路径中出现以下错误 JRE System Library WebSphere v6 1 JRE unbound 谁知道怎么修它 右键单击项目 特性 gt Java 构建路径 gt 图书馆 gt JRE
  • 仅将 char[] 的一部分复制到 String 中

    我有一个数组 char ch 我的问题如下 如何将 ch 2 到 ch 7 的值合并到字符串中 我想在不循环 char 数组的情况下实现这一点 有什么建议么 感谢您花时间回答我的问题 Use new String value offset
  • 如何从终端运行处理应用程序

    我目前正在使用加工 http processing org对于一个小项目 但是我不喜欢它附带的文本编辑器 我使用 vim 编写所有代码 我找到了 pde 文件的位置 并且我一直在从 vim 中编辑它们 然后重新打开它们并运行它们 重新加载脚
  • 获取 JVM 上所有引导类的列表?

    有一种方法叫做findBootstrapClass对于一个类加载器 如果它是引导的 则返回一个类 有没有办法找到类已经加载了 您可以尝试首先通过例如获取引导类加载器呼叫 ClassLoader bootstrapLoader ClassLo
  • 静态变量的线程安全

    class ABC implements Runnable private static int a private static int b public void run 我有一个如上所述的 Java 类 我有这个类的多个线程 在里面r
  • 在 Maven 依赖项中指定 jar 和 test-jar 类型

    我有一个名为 commons 的项目 其中包含运行时和测试的常见内容 在主项目中 我添加了公共资源的依赖项
  • 当我从 Netbeans 创建 Derby 数据库时,它存储在哪里?

    当我从 netbeans 创建 Derby 数据库时 它存储在哪里 如何将它与项目的其余部分合并到一个文件夹中 右键单击Databases gt JavaDB in the Service查看并选择Properties This will
  • 将 List 转换为 JSON

    Hi guys 有人可以帮助我 如何将我的 HQL 查询结果转换为带有对象列表的 JSON 并通过休息服务获取它 这是我的服务方法 它返回查询结果列表 Override public List

随机推荐

  • 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