从源码理解Scala中函数reduceRight的计算过程

news2024/11/24 20:59:23

水善利万物而不争,处众人之所恶,故几于道💦

  以List集合为例,进行reduceRight()的计算过程分析,总体分为两部分,一部分是看最顶层特质的那个通用的reduceRight方法,另一部分是讲直接混入的特质的那个重写的reduceRight方法,两种方式最终结果一致。


例如:
val list2: List[Int] = List(3, 4, 5, 8, 10)
println(list2.reduceRight(_ - _))   // 6

  上面的这两行代码输出的结果是6
  接下来我们从源码的角度刨析一下这个结果是怎么算出来的

  1. 首先我们点进list的reduce里面,查看他的源代码

在这里插入图片描述

  1. 点进去后在这个特质里面找到reduceRight方法
      这个方法它首先是判断了一下方法调用这也就是哪个集合是否为空,如果为空,直接抛异常。
      其次他就开始进行reduceRight的操作。看代码,他的操作是:将集合反转,然后调用reduceLeft方法,这个op就是我们的_-_操作,也就是简化/规约的逻辑。它具体执行的时候将传入的两个参数进行了位置调换。

在这里插入图片描述

举例来说:List(3, 4, 5, 8, 10).reduceRight(_ - _)

  1. 它先把集合反转得到List(10, 8, 5, 4, 3).reduceLeft(_ - _)

  2. 然后在进行相减操作的时候,传入的参数本来是(x,y)也就是x=10,y=8 但是它方法体中调用的时候是op(y, x)也就是op(8, 10)

  3. 带入到我们的例子中就是:8-10,然后 5-(8-10) ,4-(5-(8-10)) , 3-(4-(5-(8-10)))。算出最总结果是6



刚才那个reduceRight是最顶层特质的方法实现,也最容易看懂。所以先把那个最容易的看懂。

下面这个是真正执行的时候走的方法。

在这里插入图片描述

这两个特质是父子关系,LinearSeqOptimized特质是TraversableOnce特质的子特质,

TraversableOnce特质里面的reduceRight方法实现就是:

def reduceRight[B >: A](op: (A, B) => B): B = {
  if (isEmpty)
    throw new UnsupportedOperationException("empty.reduceRight")

  reversed.reduceLeft[B]((x, y) => op(y, x))
}

实际上走的LinearSeqOptimized特质里面的reduceRight方法其实是对父特质里面reduceRight方法的重写。

在这里插入图片描述

查看TraversableOnce特质的层次结构,看到LinearSeqOptimized特质是它的子特质。

在这里插入图片描述

实际上走的是这段代码:

override /*IterableLike*/
def reduceRight[B >: A](op: (A, B) => B): B =
  if (isEmpty) throw new UnsupportedOperationException("Nil.reduceRight")
  else if (tail.isEmpty) head
  else op(head, tail.reduceRight(op))

 1. 首先它判断了一下集合是否为空,空的话直接抛异常

 2. 否则判断集合的尾是否为空,如果为空的话直接将头部返回。意思就是,如果集合中只有一个元素的话,直接将该元素返回。

 3. 接下来进行我们的简化/规约操作,op是我们传过来的函数,也就是(a:Int,b:Int)=>{a-b}。op的第一个参数是集合的头,也就是3,第二个参数是尾再进行reduceRight(op)操作,可以看到有递归调用,所以第一次执行后的结果是:

3 - List(4,5,8,10).reduceRight(_-_)  // 第一次执行

然后递归调用,第二次执行...

3 - (4 - List(5,8,10).reduceRight(_-_)) // 第二次递归调用

3 - (4 - (5 - List(8,10).reduceRight(_-_)))  //第三次递归调用

3 - (4 - (5 - (8 - List(10).reduceRight(_-_))))  //第四次递归调用

第五次递归调用的时候,由于集合中只有一个元素,
在进行 else if 条件判断的时候,返回 10 ,也就是到了递归出口

3 - (4 - (5 - (8 - 10)))  //第五次递归调用

最终算出结果是 6

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

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

相关文章

【Linux】分布式存储系统 Ceph

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 分布式存储系统 Ceph Ceph 概述1、Ceph 简介2、存储基础3、Ceph 优势4、Ceph 架构4、Ceph 核心组件5、OSD 存储后端6、Ceph 数据的存储过程7、Ceph 版本发行生命周期 Ceph 集…

Day13 02-Linux常用命令汇总

文章目录 第三章 Linux的常用命令【重要】3.1 命令格式的说明3.2 帮助命令3.2.1 man3.2.2 help 3.3 文件处理命令3.3.1 cd3.3.2 ls3.3.3 pwd3.3.4 mkdir3.3.5 touch3.3.6 echo3.3.7 cp3.3.8 mv3.3.9 rm3.3.10 vi编辑器3.3.11 ln 3.4 查看命令3.4.1 cat3.4.2 more3.4.3 head3.4.…

代码量、代码行数计算工具

cloc 极客命令行工具 下载地址:https://github.com/AlDanial/cloc 常用命令: // 文件夹的名称 cloc ./StaticAnalyzer/计算结果: 速度快,结果精准,十分实用!

51单片机学习--数码管显示

首先实现静态数码管显示 SMG表示共阴极 ,要让第三位显示数字6,需要LED6端口接0,即Y50,5的二进制为101,按P2_4 到 P2_2 的顺序接,则CBA分别接101 然后在数码管另一端,需要点亮的接上1&#xff…

亚信科技荣任「DBL电信行业工作组」副组长单位,AntDB数据库连年入选《中国数据库产品图谱》

日前,“2023可信数据库发展大会”在京圆满召开。亚信科技凭借自研的电信级核心交易数据库AntDB在通信行业15年的技术积累和行业贡献,成功当选为数据库应用创新实验室(DBL)电信行业工作组副组长单位。AntDB数据库连续两年入选《全球…

客户案例 | 数字化加速,金融企业实现3D打印式应用程序开发

关键发现: 客户痛点:传统开发周期长,流程复杂,难以满足杭银消金在企业快速发展过程中的应用开发需求;内部业务因为优先级不高,导致开发资源分配有限,更加迟滞了管理部门数字化转型的进度。 解决…

大规模新能源并网下火电机组深度调峰优化调度

1主要内容 程序主要参考《大规模新能源并网下火电机组深度调峰优化调度》,建立了深度调峰基础模型,采用IEEE30节点系统,通过直流潮流建模,以火电机组运行成本、开机成本等综合运行成本最低为目标函数,包括潮流约束、旋…

Spring 能解决所有循环依赖吗?

以下内容基于 Spring6.0.4。 看了上篇文章的小伙伴,对于 Spring 解决循环依赖的思路应该有一个大致了解了,今天我们再来看一看,按照上篇文章介绍的思路,有哪些循环依赖 Spring 处理不了。 严格来说,其实也不是解决不了…

基于Python的汉字字频统计实验

完整资料进入【数字空间】查看——baidu搜索"writebug" 实验内容 针对不同语料统计汉字的字频,并进行比较。 实验要求和目的 给出前 100 个汉字高频字的频率统计结果; 分别给出前 1、20、100、600、2000、3000、6000 汉字的字频总和&…

makefile项目管理-规则和过程

目录 1、makefile基本规则 2、makefile执行过程 3、makefile的运行规则 1、makefile基本规则 (1)命名:makefile 和 Makefile (2)makefile文件:里面是多个命令的集合,使用make命令执行该文件 …

岩土工程安全监测振弦传感器的发展史

岩土工程安全监测振弦传感器的发展史 岩土工程安全监测是岩土工程学科领域的一个重要组成部分。随着科学技术的不断发展,传感器技术的应用也在不断地创新和完善。振弦传感器是一种重要的监测设备,其应用范围广泛,以其高灵敏度、高精度、长期…

Python实现HBA混合蝙蝠智能算法优化BP神经网络回归模型(BP神经网络回归算法)项目实战

说明:这是一个机器学习实战项目(附带数据代码文档视频讲解),如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 蝙蝠算法是2010年杨教授基于群体智能提出的启发式搜索算法,是一种搜索全局最优解的有效方法…

EPSG代号-坐标系对应表

前言 EPSG 用于标识不同的地理空间参考系统,包括坐标系统、地理坐标系、投影坐标系等。这些标识符可用于许多应用程序和地理信息系统软件,以确保数据在不同系统之间的正确转换和处理。现在,EPSG已被Open Geospatial Consortium(OG…

Js: 读取数据并动态生成表格(读取新数据时,应该删除之前已经渲染出来的数据)

前言 使用JS读取数据并动态生成表格,但是发现在读取新一轮的数据时,新数据是在之前已经渲染的数据后面进行追加。因此需要解决的问题是:在读取新数据之前,把之前已经渲染的数据进行清空。 解决 1、首先写出表格的表头和主干 &…

rsync增量原理,及C++实现

1、目标端将目标文件按700字节为大小分块计算强弱校验值(强:md5 弱:adler32,注:弱校验码计算量小速度快,先比对弱校验码,弱校验值一样再比对强校验码),再结合块号组成一…

【代码随想录 | Leetcode | 第五天】链表 | 移除链表元素 | 设计链表

前言 欢迎来到小K的Leetcode|代码随想录|专题化专栏,今天将为大家带来移除链表元素和设计链表的分享✨ 目录 前言203. 移除链表元素707. 设计链表总结 203. 移除链表元素 ✨题目链接点这里 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所…

Nginx 解析漏洞复现

Nginx 解析漏洞复现 一、环境搭建二、漏洞原理三、漏洞复现 一、环境搭建 如下介绍kali搭建的教程 cd ~/vulhub/nginx/nginx_parsing_vulnerability // 进入指定环境 docker-compose up -d // 启动环境docker-compose ps使用这条命令查看当前正在运行的环境 访问http://y…

生成对抗网络与优化算法(第十次组会)

生成对抗网络与优化算法(第十次组会) 生成对抗网络(Generative Adversarial Network)优化算法生成对抗网络(Generative Adversarial Network) 优化算法

126、仿真-基于51单片机16×16点阵滚动显示仿真设计(Proteus仿真+程序+配套资料等)

方案选择 单片机的选择 方案一:STM32系列单片机控制,该型号单片机为LQFP44封装,内部资源足够用于本次设计。STM32F103系列芯片最高工作频率可达72MHZ,在存储器的01等等待周期仿真时可达到1.25Mip/MHZ(Dhrystone2.1)。内部128k字节…

-bash: ./est.sh: /bin/bash^M: 坏的解释器: 没有那个文件或目录

方法一: 方法二: sed -i s/\r$// xxx.sh