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

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

  以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) headelse 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.hqwc.cn/news/27556.html

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

相关文章

数据结构顺序表,实现增删改查

一、顺序表结构体定义 #define MAXSIZE 8 //定义常量MAXSIZE,表示数据元素的最大个数为8 typedef int datatype; //重定义int类型,分别后期修改顺序表中存储的数据类型 typedef struct {int len; //顺序表长度datatype data[MAXSIZE…

Mysql 备份与还原

目录 一、数据备份的重要性 二、数据库备份类型 2.1 物理备份 2.2 逻辑备份 三、常见的备份方法 3.1 物理冷备 3.2 专用备份工具 mysqldump 或 mysqlhotcopy 3.3 启用二进制日志进行增量备份 3.4 第三方工具备份 四、MySQL完全备份 五、数据库完全备份分类…

【学会动态规划】不同路径 II(6)

目录 动态规划怎么学? 1. 题目解析 2. 算法原理 1. 状态表示 2. 状态转移方程 3. 初始化 4. 填表顺序 5. 返回值 3. 代码编写 写在最后: 动态规划怎么学? 学习一个算法没有捷径,更何况是学习动态规划, 跟我…

算法提高-动态规划-背包问题

背包问题 01背包AcWing 423. 采药AcWing 1024. 装箱问题AcWing 1022. 宠物小精灵之收服AcWing 278. 数字组合AcWing 1023. 买书AcWing 426. 开心的金明 完全背包AcWing 1021. 货币系统AcWing 532. 货币系统 多重背包AcWing 1019. 庆功会单调队列优化AcWing 6. 多重背包问题 III…

Kubernetes - HPA-VPA - metrics介绍和安装 - HPA实验

目录 参考文章:(97条消息) Kubernetes-自动扩展器HPA、VPA、CA_hpa vpa_SRE运维充电站的博客-CSDN博客 HPA VPA 官方网址:autoscaler/vertical-pod-autoscaler at master kubernetes/autoscaler GitHub HPA和VPA进行扩缩容的区别: me…

【JavaEE】HTTP请求的构造

目录 1、通过form表单构造HTTP请求 2、通过JS的ajax构造HTTP请求 3、Postman的安装和简单使用 常见的构造HTTP请求的方式有一下几种: 直接通过浏览器的地址栏,输入一个URL,就可以构造一个GET请求HTML中的一些特殊标签,也会触发…

使用Python和Scrapy实现抓取网站数据

Scrapy是一个功能强大的网络爬虫框架,允许开发者轻松地抓取和解析网站内容,这篇文章主要为大家介绍了如何使用Python的Scrapy库进行网站数据抓取,需要的可以参考一下 在本文中,我们将介绍如何使用Python的Scrapy库进行网站数据抓…

ORA-27086: unable to lock file - already in use

数据库设计的定时任务,逻辑导出出现报错,ORA-27086: unable to lock file - already in use 检查文件目录权限,磁盘空间和定时脚本均没有发现异常 检查无果后在网上找到原因应该在于NFS自动挂载上没有nolock属性 先 umount /bak 修改/et…

BTP Integration Suite学习笔记 - (Unit3) Developing with SAP Integration Suite

BTP Integration Suite学习笔记 - (Unit1) Developing with SAP Integration Suite BTP Integration Suite学习笔记 - (Unit2) Developing with SAP Integration Suite 带着一个问题去学:明明可以直接访问一个后端系统的OData服务,为什么还要再多绕一道C…

Servlet 生命周期

文章目录 Servlet 生命周期主要有三个方法● 示意图● 初始化阶段● 处理浏览器请求阶段(service 方法)● 终止阶段 destory 方法(体现 Servlet 完整的生命周期)● 代码演示 Servlet 生命周期 主要有三个方法 ​ 1. init()初始化阶段 ​ 2. service()处理浏览器请求阶段 ​…

文心一言 VS 讯飞星火 VS chatgpt (60)-- 算法导论6.4 4题

文心一言 VS 讯飞星火 VS chatgpt (60)-- 算法导论6.4 4题 四、证明:在最坏情况下,HEAPSORT 的时间复杂度是Ω (nlgn)。 文心一言: 要证明在最坏情况下,HEAPSORT 的时间复杂度是 Ω(n log n)&#xff0c…

DKN和KGC阅读

1. DKN 作者将外部知识图包含的知识融入新闻嵌入。 (1)将新闻标题单词词嵌入,单词链接的实体嵌入,以及实体的上下文嵌入(邻居实体嵌入的平均)建模为CNN输入的三个通道。 (2)然后使用KCNN模型&#xff0c…