Java中的函数式编程1

Functional Programming In OOP

引言

函数式编程是一种编程泛型,将所有的运算都视为函数,只要输入相同的数据,就能得到稳定的输出。然而由于它的抽象程度高,离计算机硬件远,因此并没有被工业界广泛使用。然而在许多面向对象的编程语言中,能看到函数式编程的影子,它们往往可以帮助我们减少代码重复、理解目标和代码管理等。所以,学习一定的函数编程思想是非常有必要的。本文主要以Java为示例,讲解在OOP语言中函数式编程的应用。

什么是函数?

作为一个理/工科生,一说到函数,也许就会想到数学定义上的函数:一个集合到另一个集合的双射。更加直观的说,函数就是:我们只要输入一些数据就能得到一些数据。这样的数据转换是由函数内部实现所决定的。当然把函数当成一种算法的实现也没有问题。总之一千个人眼中有一千个哈姆雷特,只要选择你自己能够理解的方法,理解它就可以了。

那么在计算机领域,函数有如下的一些特点:

  1. 每个函数的输入是确定的(数据的类型、个数)。
  2. 每个函数的输出是确定的(数据的类型),并且只能输出一个数据。
  3. 函数的内部应当避免使用程序状态可变对象

第一、二点很容易理解,函数体内部的实现依赖于输入和需求,而输出则依赖于函数的内部实现和输入,需求和函数内部实现是固定的,因此函数的输入和输出也应该是确定的。

函数可以没有输入或输出,但它会执行特定的功能。

对于第三点的理解,由于函数的内部实现的固定,因此不能把变化的(程序状态和可变对象)用在不变中。

什么是函数式编程?

在理解了函数是什么以后,我们就可以更进一步理解函数式编程了。

不同于OOP中万物皆对象的思想,函数式编程的思想更加的直接。将一系列的语句封装成多个不同的函数,从而解决一个复杂的问题;它聚焦于如何解决问题和表达式,而不是状态。

函数式方程还有以下特点:

  1. 递归:函数式编程采用递归处理while、if、for。
  2. 函数皆变量:所有的函数都可以当做变量使用。
  3. 不可变性:任何变量被创建以后都不能改变

函数式编程的优点:

  1. 易于debug
  2. Lazy evaluation:只在使用的时候运行函数。
  3. 支持并行编程:由于函数式编程使用不可变变量,因此可以轻松的实现并行编程,也不会有安全隐患。
  4. 易读:函数式编程的代码具有相当的易读性。
  5. 高效:函数式编程不依赖于外部资源或者变量,因此它们可以轻易的复用。

函数式编程的缺点:

  1. 术语复杂:函数编程的学习成本高。
  2. 递归:递归可能会造成资源浪费。

Java中函数式编程的应用

在Java中,函数式编程也有相当的应用场景。例如,对于一个排序算法:在不同的场景下可能要求升序或降序排列,为提高排序算法的可复用性,往往会需要一个东西,来控制排序的方式,也许可以是一个flag,若为1则升序,反之则降序。然而,通过这样的方式控制排序,过程中我们就必须重复书写一些代码,可以参考以下快速排序的实现。

    /*** 快速排序* * @param arr   原数组* @param begin 起始元素* @param end   终止元素*/public static void quickSort(int[] arr, int begin, int end, int flag) {if (begin >= end) {return;}int pivot = begin;int i = begin;if(flag == 1){for (int j = begin + 1; j <= end; ++j) {if (arr[j] < arr[pivot]) {swap(arr, ++i, j);}}}else {for (int j = begin + 1; j <= end; ++j) {if (arr[j] > arr[pivot]) {swap(arr, ++i, j);}}}swap(arr, i, pivot);quickSort(arr, pivot + 1, end, flag);quickSort(arr, begin, pivot - 1, flag);}

可以看到:for循环中除了比较大小不同,其它代码都相同。那么有没有什么办法,可以让我们避免重复书写相同代码呢?相信在看完函数式编程的简介以后,你就想到把一个函数当做参数传入方法中。那么接下来我们就要介绍如何使用这样的方法。

Java作为一个纯粹的OOP语言,万物皆为对象,所以我们所需要的函数参数也应该封装为一个类,这个类就代表着一个函数。显然这样的类不需要任何字段和其它方法,它的内部只有一个方法(封装的函数),因此使用接口(interface)来表示这个类最为恰当。

再回到快速排序这个例子,我们针对不同的排序方法,要使用同一段代码实现,所以我们需要函数既能表示“大于”,也能表示“小于”。一个函数两个作用,这显然涉及到了方法的覆写(@Override),现在思路就很清晰了,我们需要传入的函数参数应该是封装了函数的接口的具体实现类,在这个类中覆写了接口中的函数。

这就是在Java中使用函数作为参数的实现思路,那么具体实现将在下一节探讨。

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

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

相关文章

掌握App用户注册情况,Xinstall来帮忙

在移动互联网时代&#xff0c;App已经成为企业与用户之间的重要桥梁。然而&#xff0c;对于许多App开发者来说&#xff0c;如何精准地获取和分析用户注册数据&#xff0c;一直是一个令人头疼的问题。幸运的是&#xff0c;有了Xinstall这样的一站式App全渠道统计服务商&#xff…

java八股文知识点讲解(个人认为讲的比较好的)

1、解决哈希冲突——链地址法&#xff1a;【第7章查找】19哈希表的查找_链地址法解决哈希冲突_哔哩哔哩_bilibili 2、解决哈希冲突——开放地址法 &#xff1a; 【第7章查找】18哈希表的查找_开放定址法解决哈希冲突_哔哩哔哩_bilibili 3、小根堆大根堆的创建&#xff1a;选择…

Ubuntu 忘记系统密码 如何修改密码

如果你忘记了Ubuntu系统的密码&#xff0c;你可以通过以下方法来修改密码&#xff1a; 通过GRUB引导菜单进入恢复模式 重启系统并进入GRUB引导菜单&#xff1a; 重启Ubuntu系统&#xff0c;并在启动时连续按Shift键&#xff08;或根据系统提示的其他按键&#xff09;&#xf…

Smart - Luogu —— 智能的洛谷

文章目录 安装 Stylus谷歌Edge 安装 Smart - Luogu使用尾声 安装 Stylus link 点击推荐下载&#xff0c;获取 crx 文件 谷歌 先点击右上角三个点&#xff0c;再点击扩展程序&#xff0c;然后点击管理扩展程序&#xff0c;进入管理扩展界面&#xff0c;把开发者模式选上&…

NL2SQL进阶系列(5):论文解读业界前沿方案(DIN-SQL、C3-SQL、DAIL-SQL、SQL-PaLM)、新一代数据集BIRD-SQL解读

NL2SQL进阶系列(5)&#xff1a;论文解读业界前沿方案&#xff08;DIN-SQL、C3-SQL、DAIL-SQL&#xff09;、新一代数据集BIRD-SQL解读 NL2SQL基础系列(1)&#xff1a;业界顶尖排行榜、权威测评数据集及LLM大模型&#xff08;Spider vs BIRD&#xff09;全面对比优劣分析[Text2…

【C++进阶】详解C++类型转换IO流

C类型转换及IO流 一&#xff0c;C语言的类型转换方式二&#xff0c;C的四种强制类型转换方式2.1 static_cast2.2 reinterpret_cast2.3 const_cast2.4 dynamic_cast 三&#xff0c;C语言的输入和输出四&#xff0c;C的标准IO流五&#xff0c;C文件IO流总结 这一节我们来讲解 C的…

数据结构OJ:设计循环队列

题目介绍 本题为LeetCode上的经典题目&#xff0c;题目要求我们设计一种循环队列&#xff0c;满足FIFO原则且队尾被连接在队首之后。 思路讲解 题目中介绍循环队列的好处是可以重复利用空间&#xff0c;所以我们很容易想到在初始化时即开辟指定大小的空间&#xff0c;之后便不…

策略模式:灵活调整算法的设计精髓

在软件开发中&#xff0c;策略模式是一种行为型设计模式&#xff0c;它允许在运行时选择算法的行为。通过定义一系列算法&#xff0c;并将每个算法封装起来&#xff0c;策略模式使得算法可以互换使用&#xff0c;这使得算法可以独立于使用它们的客户。本文将详细介绍策略模式的…

【小贪】大数据处理常用:Pyspark, Pandas

近期致力于总结科研或者工作中用到的主要技术栈&#xff0c;从技术原理到常用语法&#xff0c;这次查缺补漏当作我的小百科。主要技术包括&#xff1a; ✅数据库常用&#xff1a;MySQL, Hive SQL, Spark SQL✅大数据处理常用&#xff1a;Pyspark, Pandas⚪ 图像处理常用&#…

【每日刷题】Day16

【每日刷题】Day16 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 24. 两两交换链表中的节点 - 力扣&#xff08;LeetCode&#xff09; 2. 160. 相交链表 - 力扣&…

基于小程序实现的4s店管理系统

作者主页&#xff1a;Java码库 主营内容&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 技术选型 【后端】&#xff1a;Java 【框架】&#xff1a;ssm 【…

【C++11】智能指针

> 作者&#xff1a;დ旧言~ > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;理解在C11中智能指针&#xff0c;自己能模拟实现 4 种智能指针 > 毒鸡汤&#xff1a;白日莫闲过&#xff0c;青春不再来。 > 专栏选自&#xff1…

【halcon】C# halcon 内存暴增 续,找到一个解决方案

这里写自定义目录标题 背景释放临时缓存具体的使用感受背景 在之前的文章《【halcon】C# halcon 内存暴增 》中我们提到了一些会导致内存暴增的原因。 其中一个就是使用了计算复杂的算子,且图片很大时,此时内存就会暴增,而且内存无法被释放。 这次,我在做一个项目时,用到…

深入理解负载均衡:原理及常用算法

摘要&#xff1a; 负载均衡在现代网络架构中扮演着至关重要的角色&#xff0c;它通过分配请求到多个服务器来提高系统的性能、可用性和可伸缩性。本文将介绍负载均衡的基本原理以及常用的负载均衡算法&#xff0c;帮助读者更好地理解和应用负载均衡技术。 引言 随着互联网的迅…

TP5使用group报错:1055 Expression #1 of SELECT list is not in GROUP

使用group报错 Mysql环境是5.7的, 使用了View进行了表连接, 进行了表连接 搬迁到本地后, 查询报错 Syntax error or access violation: 1055 Expression 解决方法1 配置 my.cnf(linux)文件 win下面是 mysql.ini文件 在 mysqld 里加上 sql_modeNO_ENGINE_SUBSTITUTION,STR…

L2-3 完全二叉树的层序遍历

完全二叉树的层序遍历 一个二叉树&#xff0c;如果每一个层的结点数都达到最大值&#xff0c;则这个二叉树就是完美二叉树。对于深度为 D 的&#xff0c;有 N 个结点的二叉树&#xff0c;若其结点对应于相同深度完美二叉树的层序遍历的前 N 个结点&#xff0c;这样的树就是完全…

网络爬虫:定义、应用及法律道德考量

网络爬虫技术在当今数据驱动的世界中发挥着重要作用。本文将从网络爬虫的定义和主要功能&#xff0c;其在业界的应用实例&#xff0c;以及涉及的法律和道德问题三个方面进行深入探讨。 1. 爬虫的定义和主要功能 网络爬虫&#xff0c;也称为网页爬虫或蜘蛛&#xff0c;是一种…

RocketMQ 01 Linux安装

RocketMQ 01 主要内容&#xff1a; 编译安装HelloWorld官网名词 官方网站 http://rocketmq.apache.org GitHub https://github.com/apache/rocketmq Quick Start Linux下使用Maven编译源码安装 Rocketmq4.6需要jdk1.8环境编译和运行 各版本要求 VersionClientBroke…

SGI_STL和Nginx内存池源码剖析--源码移植

将SGISTL内存配置器和Nginx内存池源码&#xff0c;移植到自己的项目中。 源码文件复杂&#xff0c;并且有很多项目中使用不到的宏定义&#xff0c;所以通过改写和移植&#xff0c;可以很好的适应C的其他项目。 SGI-STL源码移植资源-CSDN文库 nginx内存池源码移植资源-CSDN文库…

游戏动画技术:从传统到深度学习

一、传统游戏动画技术简介 3D游戏动画的骨骼动画和蒙皮技术动画交互控制&#xff1a;状态机、动作融合和IK基于状态机的动画控制原理和问题 二、Motion Matching技术简介 传统状态机动画的缺陷Motion Matching的原理&#xff1a;根据角色状态自动匹配动画Dance Card动捕流程…