Java8函数式编程(Lambda表达式,Stream流,Optional)

news2024/11/15 13:31:40

一.函数式编程思想

  • 面向对象思想主要是关注对象能完成什么事情,函数式编程思想就像函数式,主要是针对数据操作;
  • 代码简洁容易理解,方便于并发编程,不需要过分关注线程安全问题

二.lambda表达式

1.概念

lambda表达式是Java8的一个新特性,从本质上来讲是一个匿名函数可以使用这个匿名函数实现接口中的方法,并且非常简洁。

通常来讲,使用 lambda表达式 是为了简化接口实现的。关于接口实现,可以有很多种方式来实现。例如L设计接口的实现类、使用匿名内部类。但是lambda表达式比这两种方式都简单。可以把lambda看成JDK8中的一个语法糖。

2.Lambda表达式对接口的要求

并不是所有的接口都可以使用lambda表达式来简洁实现的。lambda表达式毕竟只是一个匿名方法。当实现的接口中的方法过多或者过少的时候,lambda表达式都是不适用的。

lambda表达式只能实现函数式接口。即一个接口中,要求实现类必须实现的抽象方法,有且只有一个,这样的接口就是函数式接口。

3.Lambda表达式的语法

(参数)->{方法体}
  • 参数部分︰方法的参数列表,要求和实现的接口中的方法参数部分一致,包括参数的数量和类型
  • 方法体部分∶方法的实现部分,如果接口中定义的方法有返回值,则在实现的时候,注意返回值的返回。
  • ->:分隔参数部分和方法体部分。 

  • 因为接口中规定了方法参数类型,所以实际写lambda表达式的时候可以省略 参数类型。如果只有一个参数,可以省略()
  • 另外如果方法体里只有一个语句,那么可以省略掉 {},如果该语句是return语句,需要把return也省略掉

省略如下:

4.函数引用

lambda表达式是为了简化接口的实现的。在lambda表达式中,不应该出现比较复杂的逻辑。如果在lambda表达式中出现了过于复杂的逻辑,会对程序的可读性造成非常大的影响。

如果在lambda表达式中需要处理的逻辑比较复杂,一般情况会单独的写一个方法。在lambda表达式中直接引用这个方法即可。或者,在有些情况下,我们需要在lambda表达式中实现的逻辑,在另外一个地方已经写好了。此时我们就不需要再单独写一遍,只需要直接引用这个已经存在的方法即可。

函数引用:引用一个已经存在的方法,使其替代lambda表达式完成接口的实现。

4.1引用一个静态方法

接口依然是上面的MultipleParametersReturn,引用如下 

需要注意的是引用的 方法的参数返回值类型 要与 接口 对应

4.2引用一个非静态方法

4.3引用构造方法 

Person类

public class Person {
    private Integer age;
    private String name;

    public Person() {
    }

    public Person(Integer age) {
        this.age = age;
    }

    public Person(Integer age, String name) {
        this.age = age;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

PersonWithNoParam接口

@FunctionalInterface
public interface PersonWithNoParam {
    Person getPersonWithNoParam();
}

PersonWithOneParam接口

@FunctionalInterface
public interface PersonWithOneParam {
    Person getPersonWithOneParam(Integer age);
}

PersonWithDoubleParams接口

@FunctionalInterface
public interface PersonWithDoubleParams {
    Person getPersonWithDoubleParams(Integer age,String name);
}

Demo

public class Demo1 {
    public static void main(String[] args) {
        //lambda表达式实现PersonWithNoParam接口
        PersonWithNoParam t1=Person::new;//无参构造函数引用
        System.out.println(t1.getPersonWithNoParam());

        //lambda表达式实现PersonWithOneParam接口
        PersonWithOneParam t2=Person::new;//单参构造函数引用
        System.out.println(t2.getPersonWithOneParam(10));

        //lambda表达式实现PersonWithDoubleParams接口
        PersonWithDoubleParams t3=Person::new;//多参构造函数引用
        System.out.println(t3.getPersonWithDoubleParams(10,"小王"));

    }

}

lambda表达式会自动根据 方法的参数类型 匹配Person类中对应的构造方法

5.特殊的函数引用

如果在使用lambda表达式实现某些接口的时候,lambda表达式的参数列表中包含了某一个对象,此时方法体中,直接使用这个对象调用它的某一个方法就可以完成整体的逻辑并且其他的参数可以作为调用方法的参数。此时,可以对这种实现进行简化。

Person类

public class Person {
    private Integer age;
    private String name;

    public Person() {
    }

    public Person(Integer age) {
        this.age = age;
    }

    public Person(Integer age, String name) {
        this.age = age;
        this.name = name;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

PersonSpecial接口

public interface PersonSpecial {
    void setAge (Person person,Integer age);
}

Demo2

public class Demo2 {
    public static void main(String[] args) {
        //简化前
        PersonSpecial t=(person,age)->person.setAge(age);
        //用对象的特殊引用简化后
        PersonSpecial t2=Person::setAge;
        Person person = new Person();
        t2.setAge(person,13);
        System.out.println(person);
    }
}

6.闭包

如果某一个局部变量被用在了某一个代码块中,这其实就形成了对这个局部变量的包围,我们称"闭包"。这个时候这个变量不允许被改变,即final

如下编译器会报错:

如果使用的是全局变量则不会出现闭包问题 

三.Stream流

Java8的 使用的是函数式编程模式,可以被用来对集合或数组进行链状流式的操作。有别于IO流,这里是针对集合操作数据的流

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/453347.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

提升金融写作效率:金融校对软件的优势与应用

金融行业的写作任务繁重且要求高度专业,涉及财务报告、研究报告、合同、政策文件等各类文档。金融校对软件应运而生,为金融专业人士提供有效的支持,帮助他们提高写作效率和质量。本文将探讨金融校对软件的优势与应用。 一、金融校对软件的优势…

【NFS共享存储服务】

目录 一、NFS (Network File System)网络文件系统1.1、NFS工作原理1.2、举例1.2.1、共享文件总结 一、NFS (Network File System)网络文件系统 依赖于RPC (远端过程调用) 需安装nfs-utils、rpcbind软件包 系统服务: nfs、rpcbind 共享配置文件: /etc/ex…

跳表的实现

目录 简介跳表的实现 简介 skiplist本质也是一种查找结构,和搜索树、哈希表一样可以作为key或者key/value模型的查找结构,从命名可以看出它也是一个链表结构,链表的查找效率是O(n),作为在链表基础上优化的一种查找结构,跳表的查找…

app拉新充场代理

我认为您可能是想了解APP充值拉新软件的功能吧。通常,APP充值拉新软件会具有以下功能: 充值服务:提供多种支付方式,让用户方便快捷地进行充值操作。 活动推广:通过不同的方式,如折扣、优惠码等&…

Tomcat的部署和优化

Tomcat的组件构成 (1)Web 容器:完成 Web 服务器的功能。 (2)Servlet 容器:名字为 catalina,用于处理 Servlet 代码。 (3)JSP 容器:用于将 JSP 动态网页翻译成…

centos系统安装mysql8.0

centos系统安装mysql8.0 环境说明开始1、查看centos7中是否有MariaDB,MariaDB与MySQL关系请自行查阅2、如果有MariaDB,需要将 步骤1 中查询到的mairadb全部卸载,否则MySQL安装会出现问题3、查看本机是否已经安装过MySQL4、如果安装过MySQL&am…

9.java程序员必知必会类库之加密库

前言 密码学在计算机领域源远流长,应用广泛。当前每时每刻,每一个连接到互联网的终端,手机,电脑,iPad都会和互联网有无数次的数据交互,如果这些数据都是明文传输那将是难以想象的。为了保护用户隐私&#…

算法--前缀和技巧 (蓝桥杯123-灵能传输)

文章目录 什么是前缀和用途什么时候用例题[蓝桥杯 2021 国 ABC] 123题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示 思路代码 灵能传输(蓝桥杯96%,洛谷ac)[蓝桥杯 2019 省 B] 灵能传输题目背景题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1…

知识图谱实战开篇-讲述知识图谱是什么,要学哪些知识,一文讲通

大家好,我是微学AI,今天给大家带来知识图谱重要讲述,讲明白什么是知识图谱,知识图谱可以做什么,需要学哪些知识,与自然语言处理的关系。很多人认为知识图谱是关系图谱,可能涉及人工智能的东西不…

【LeetCode】650. 只有两个键的键盘

650. 只有两个键的键盘(中等) 思路 不同于以往通过加减实现的动态规划,这里需要乘除法计算位置。因为粘贴操作是倍数增加,使一个一维数组 dp,其中位置 i 表示延展到长度 i 的最少操作次数。对于每个位置 j &#xff0c…

C++学习 Day6

目录 1. 类对象模型 1.1 如何计算类对象的大小 1.2 类对象的存储方式 1.3 结构体内存对齐规则 2. this指针 2.1 this指针的引出 2.2 this指针的特性 3. 类的6个默认成员函数 4.构造函数 4.1 概念 4.2 特性 1. 类对象模型 1.1 如何计算类对象的大小 class A { publi…

【Java】『蓝桥杯』10道编程题及答案(一)

系列文章 【Java】『蓝桥杯』10道编程题及答案(一) 本文链接:https://blog.csdn.net/youcheng_ge/article/details/130223115 【Java】『蓝桥杯』10道编程题及答案(二) 本文链接:https://blog.csdn.net/y…

【Hello Network】协议

作者:小萌新 专栏:网络 作者简介:大二学生 希望能和大家一起进步 本篇博客简介:简单介绍下协议并且设计一个简单的网络服务器 协议 协议的概念结构化数据传输序列化和反序列化网络版计算机服务端代码协议定制客户端代码服务线程执…

[Netty] HashWheelTimer时间轮 (十六)

文章目录 1.常见定时任务实现2.时间轮算法3.HashedWheelTimer源码分析3.1 内部结构分析3.2 构造方法3.3 添加任务3.4 工作线程Worker3.5 停止时间轮 4.HashWheelTimer总结 1.常见定时任务实现 定时器的使用场景包括:成月统计报表、财务对账、会员积分结算、邮件推送…

Linux Podman容器介绍

目录 Podman讲解 Container 和 Container Images 的关系 安装Podman 配置root的容器管理 国内镜像源 配置Podman的镜像源 创建容器相关命令 配置rootless的容器管理 配置Podman镜像源 管理容器镜像 管理容器 将容器作为systemd服务运行 配置普通用户来创建systemd…

Jetpack Compose之线性布局和帧布局

概述 Compose 中的线性布局对应的是Android传统视图中的LinearLayout,不一样的地方是,Compose根据Orientation的不同又将布局分为Column和Row, Column对应传统视图LinearLayout中orientation “vertical”的情况,Row对应传统视图LinearLayout中orienta…

Redis入门学习笔记【二】Redis缓存

目录 一、Redis缓存 二、Redis使用缓存遇到的问题 2.1 数据一致性 2.2缓存雪崩 2.3 缓存穿透 2.4 缓存击穿 一、Redis缓存 数据缓存是Redis最重要的一个场景,为缓存而生,在springboot中,一般有两种使用方式: 直接通过RedisT…

helm部署相关服务过程中问题记录

在学习helm部署相关服务过程中出现一些相关问题,自己记录并供大家一起学习!!! 【问题1】部署helm 获取软件包失败 在通过wget https://storage.googleapis.com/kubernetes-helm/helm-v2.13.1-linux-amd64.tar.gz文件过程发现无法…

消息中间件的定义

中间件(middleware)是基础软件的一大类,属于可复用的软件范畴。中间件在操作系统软件,网络和数据库之上,应用软件之下,总的作用是为处于自己上层的应用软件提供运行于开发的环境,帮助用户灵活、高效的开发和集成复杂的…

【软考数据库】第二章 程序语言基础知识

目录 2.1 程序设计语言的基本概念2.2 程序设计语言的基本成分2.3 编译程序基本原理 前言: 笔记来自《文老师软考数据库》教材精讲,精讲视频在b站,某宝都可以找到,个人感觉通俗易懂。 2.1 程序设计语言的基本概念 程序设计语言是…