[读书日志]从零开始学习Chisel 第八篇:Scala的集合(敏捷硬件开发语言Chisel与数字系统设计)

5.Scala的集合

Scala的集合包括数组,列表,集,映射,序列,元组,数组缓冲和列表缓冲等。

5.1 数组
5.1.1数组的定义

数组是计算机内一片地址连续的内存空间。数组元素类型可以是任意的,不同元素类型会导致每个元素的内存大小不一样,但所有元素类型必须一致。数组对象是定长的,在构造时可以选择任意长度的数组,但构造完毕就不能再更改长度了。构造数组对象的语法如下:

new Array[T](n),方框中的T表示元素个数,可以显式声明也可以自动推断;圆括号内的n代表有n个元素。Array的伴生对象中还定义了一个apply工厂方法。

scala> val charArray = Array('a','b','c')
val charArray: Array[Char] = Array(a, b, c)
5.1.2数组的索引与元素修改

数组的下标写在圆括号中,数组元素是可变的,可以对数组元素重新赋值。

scala> val intArray = new Array[Int](3)
val intArray: Array[Int] = Array(0, 0, 0)scala> intArray(0) = 1scala> intArray(1) = 2scala> intArray(2) = 3scala> intArray
val res0: Array[Int] = Array(1, 2, 3)
5.2 列表
5.2.1列表的定义

列表是一种基于链表的数据结构,列表也是定长的,每个元素类型相同,不可再重新赋值。

scala> val intList = List(1,1,10,-5)
val intList: List[Int] = List(1, 1, 10, -5)scala> intList(0)
val res1: Int = 1scala> intList(3)
val res2: Int = -5
5.2.2列表添加数据
操作符作用
::向列表的头部添加元素或列表
:::用于拼接左右两个列表
+:向列表的头部添加元素或列表
:+向列表的尾部添加元素或列表

注意,这些操作都会返回一个新的列表,因为列表是不可变的对象。其中,+:和+:在调用时必须将添加后的列表显式地赋值给另一个列表。

scala> val x = List(1)
val x: List[Int] = List(1)scala> val y = 2 +: x
val y: List[Int] = List(2, 1)scala> val z = 3 :+ x
-- [E008] Not Found Error: ---------------------------------------------------------------------
1 |val z = 3 :+ x|        ^^^^|        value :+ is not a member of Int
1 error foundscala> val z = x :+ 3
val z: List[Int] = List(1, 3)
5.2.3列表子对象Nil

列表的子对象Nil表示空列表,它的类型是List[Nothing],因为List的类型参数是协变的,所以List[Nothing]是所有列表的子类,即Nil兼容所有的元素。使用这个特性可以构造列表:

scala> 1 :: 2 :: 3 :: Nil
val res5: List[Int] = List(1, 2, 3)

数组和列表元素不仅可以是值类型,也可以是自定义的类,甚至是数组和列表本身,构成嵌套的数组和列表。如果元素类型是Any,那么数组和列表就可以包含不同类型的元素。

scala> List(Array(1,2,3),Array(10,100,100))
val res6: List[Array[Int]] = List(Array(1, 2, 3), Array(10, 100, 100))scala> List(1,'1',"1")
val res7: List[Int | Char | String] = List(1, 1, 1)

这里在新版Scala中有别于书上的内容,书上显示的是List[Any],但在最新版Scala中是三种类型的或。

5.3 数组缓冲与列表缓冲

列表可以很容易地在头部添加数据,但在尾部添加数据随着列表变大会消耗更长时间。往列表尾部添加元素很慢,所以一种方案是先往列表头部添加,再把列表整体翻转。

另一种方案是使用定义在scala.collection.mutable包中的ArrayBufferListBuffer。这两种并不是真正的数组和列表,可以将其认为是暂存在缓冲区的数据。在数组缓冲和列表缓冲的头部,尾部都能添加,删去元素,且耗时是固定的,数组缓冲比数组速度慢一些。以下是三种常用的操作符:

操作符作用
+=向缓冲的尾部添加元素
+=:向缓冲的头部添加元素
-=从缓冲的尾部开始删去第一个符合的元素

代码示例如下:

scala> import scala.collection.mutable.{ArrayBuffer, ListBuffer}scala> val ab = new ArrayBuffer[Int]()
val ab: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()scala> ab += 10
val res8: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(10)scala> -10 +=: ab
val res9: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(-10, 10)scala> val lb = new ListBuffer[String]()
val lb: scala.collection.mutable.ListBuffer[String] = ListBuffer()scala> lb += "one"
val res10: scala.collection.mutable.ListBuffer[String] = ListBuffer(one)scala> lb ++= Seq("abc","oops","good")
val res11: scala.collection.mutable.ListBuffer[String] = ListBuffer(one, abc, oops, good)scala> lb -= "abc"
val res12: scala.collection.mutable.ListBuffer[String] = ListBuffer(one, oops, good)scala> lb.toArray
val res13: Array[String] = Array(one, oops, good)scala> lb.toList
val res14: List[String] = List(one, oops, good)
5.4 元组
5.4.1元组的定义

元组也是不可变的,但可以包含不同类型的对象,使用圆括号表示。

5.4.2元组的索引

元组无法通过下标索引,只能用._n来访问每一个元素。第一个元素是._1,而不是._0

scala> val t = ("God", 'A', 2333)
val t: (String, Char, Int) = (God,A,2333)scala> t._1
val res15: String = Godscala> t._2
val res16: Char = Ascala> t._3
val res17: Int = 2333

元组并不是一个类,而是一系列类Tuple1~Tuple22,除了通过字面量的写法构造元组,也可以显式通过new TupleX(元组元素)来构造。也就是说,元组最多包含22个元素,除非自定义Tuple23等类。但是元组可以嵌套,索引元组仍然可以包含任意数量的元素。

5.4.3元组作为函数的入口函数

一元组没有字面量,只能显式地通过new Tuple1(元组元素)来构造,二元组也称为对偶,在映射中会用到。当函数的入参数量为一个时,调用函数时传递进去的元组字面量也可以省略圆括号。

scala> def getType(x: Any) = x.getClass
def getType(x: Any): Class[?]scala> getType(1)
val res18: Class[?] = class java.lang.Integerscala> getType(1,2,3)
val res19: Class[?] = class scala.Tuple3
5.4.4元组的遍历

元组数据的遍历需要先调用productIterator方法以获取其迭代器,然后对迭代器进行编译。

scala> val t1 = (1, "a", "b", true, 2)
val t1: (Int, String, String, Boolean, Int) = (1,a,b,true,2)scala> for (item <- t1.productIterator) {| println("item" + item)| }
item1
itema
itemb
itemtrue
item2
5.5 映射
5.5.1映射的定义

映射是包含一系列键-值对的集合,键和值的类型可以是任意的,但每个键-值对的类型必须一致。映射不是一个类,而是一个特质,无法通过new创建,只能通过伴生对象的apply方法来构造。

scala> val map = Map(1 -> "+", 2 -> "-", 3 -> "*", 4 -> "/")
val map: Map[Int, String] = Map(1 -> +, 2 -> -, 3 -> *, 4 -> /)

表达式object1 -> object2是一个对偶(二元组),所以键-值对也可以写成对偶的形式。

scala> val tupleMap = Map(('a', 'A'), ('b', 'B'))
val tupleMap: Map[Char, Char] = Map(a -> A, b -> B)scala> tupleMap('a')
val res20: Char = A
5.5.2映射的三种取值方式

当我们创建了一个映射,将其赋值给变量map,那么我们可以使用以下三种方式通过“键”来索引对应的“值”。

map("键"),返回对应的值,如果没有则报错;

map.get("键"),返回对应的值,如果没有则返回None

map.getOrElse(“键”,"默认值"),返回对应的值,如果没有则返回默认值。

scala> val map = Map(1 -> "+", 2 -> "-", 3 -> "*", 4 -> "/")
val map: Map[Int, String] = Map(1 -> +, 2 -> -, 3 -> *, 4 -> /)scala> map(3)
val res21: String = *scala> map(0)
java.util.NoSuchElementException: key not found: 0at scala.collection.immutable.Map$Map4.apply(Map.scala:535)... 30 elidedscala> map.get(3)
val res23: Option[String] = Some(*)scala> map.get(0)
val res24: Option[String] = Nonescala> map.getOrElse(0,'A')
val res25: String | Char = A
5.5.3映射遍历的四种方式

for((k,v) <- map),遍历所有的键和值,k是键,v是值;

for(k <- map.keys),遍历所有的键;

for(v <- map.values),遍历所有的值;

for(item <- map),遍历所有的键-值对,此时的item是元组。

默认情况下使用的是scala.collection.immutable包中的不可变映射,也可以导入scala.collection.mutable包中的可变映射,这样可以动态地增加、删除键-值对。

5.6 集

集和映射一样,也是一个特质,也只能通过apply工厂方法构建对象。集只能包含字面值不相同的同类型元素,若构建时传入了重复参数,则会自动删去多余元素。集的apply方法测试集中是否包含传入的参数,返回truefalse,而不是通过下标来索引元素。

scala> val set = Set(1,1,10,10,233)
val set: Set[Int] = Set(1, 10, 233)scala> set(100)
val res26: Boolean = falsescala> set(10)
val res27: Boolean = true

与映射相同,也可以导入scala.collection.mutable包中的可变集。

5.7 序列

序列Seq也是一个特质,数组和列表都混入了这个特质,序列可遍历,可迭代,可以用0开始的下标索引,也可用于循环。序列包含一组相同类型的元素,不可变。序列使用apply方法进行构造。

5.8 集合的常用方法
5.8.1 map

map接收一个无副作用的函数作为入参,对调用该方法的集合的每个元素应用入参函数,并把所得结果全部打包在一个集合中返回。

scala> Array("apple", "orange", "pear").map(_ + "s")
val res28: Array[String] = Array(apples, oranges, pears)scala> List(1,2,3).map(_ * 2)
val res29: List[Int] = List(2, 4, 6)
5.8.2 foreach

map类似,只不过传入的是有副作用的函数。

scala> var sum = 0
var sum: Int = 0scala> Set(1,-2,234).foreach(sum += _)scala> sum
val res30: Int = 233
5.8.3 zip

zip方法把两个可迭代的集合一一对应,构成若干对偶,如果其中一个集合比另一个长,忽略多余的元素。

scala> List(1,2,3) zip Array('1','2','3')
val res31: List[(Int, Char)] = List((1,1), (2,2), (3,3))scala> List(1,2,3) zip Set("good","OK")
val res32: List[(Int, String)] = List((1,good), (2,OK))
5.8.4 reduce

reduce的方法入参是一个二元操作函数,利用该二元操作函数对集合中的元素进行归约,即将上一步返回的值作为函数的第一个参数继续传递并参与运算,直到list中的所有元素被遍历,默认是从左到右的顺序。

(1 to 5).reduce(_ + _)		//1+2+3+4+5
(1 to 5).reduceLeft(_ + _)	//1+2+3+4+5
(1 to 5).reduceRight(_ + _)	//5+4+3+2+1
5.8.5 fold

reduce类似,但可以传入一个初始值。

(1 to 5).fold(10)(_ + _)		//1+2+3+4+5
(1 to 5).foldLeft(10)(_ + _)	//1+2+3+4+5
(1 to 5).foldRight(10)(_ + _)	//5+4+3+2+1
5.8.6 scan

fold差不多,但会把产生所有的中间结果放置在一个集合中保存。

(1 to 3).scan(10)(_ + _)		//{10,10+1,10+1+2,10+1+2+3}
(1 to 3).scanLeft(10)(_ + _)	//{10,10+1,10+1+2,10+1+2+3}
(1 to 3).scanRight(10)(_ + _)	//{10+1+2+3,10+1+2,10+1,10}

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

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

相关文章

k8s排错集:zk集群的pod报错 Init:CrashLoopBackOff无法启动

zk三节点集群&#xff0c;zk-0无法启动 statefulset 进到该node节点上查看容器的报错日志&#xff0c;发现在初始化container的时候一个命令有问题 查看正常zk集群的pod的资源配置文件 解决办法&#xff1a; 修改资源配置文件 应该修改为 chown -R 1000:1000 /zkenv kubec…

Golang的并发编程框架比较

# Golang的并发编程框架比较 中的并发编程 在现代软件开发中&#xff0c;处理高并发的能力愈发重要。Golang作为一门支持并发编程的编程语言&#xff0c;提供了丰富的并发编程框架和工具&#xff0c;使得开发者能够更轻松地处理并发任务。本文将介绍Golang中几种常用的并发编程…

【Web】软件系统安全赛CachedVisitor——记一次二开工具的经历

明天开始考试周&#xff0c;百无聊赖开了一把CTF&#xff0c;还顺带体验了下二开工具&#xff0c;让无聊的Z3很开心&#x1f642; CachedVisitor这题 大概描述一下&#xff1a;从main.lua加载一段visit.script中被##LUA_START##(.-)##LUA_END##包裹的lua代码 main.lua loca…

单纯形法的学习笔记

文章目录 A. 单纯形法概述1. 优化模型示例 B. 理论基础C. 算法思想D. 实现算法1. 线性规划的标准型2. 顶点解的理解及表示2.1 在标准型中变量取值为零的意义2.2 顶点解的表示 3. 最优性判断4. 解的更新5. 完成迭代过程 E. 单纯形法的基本概念与本文对照F. 文档源码 前言&#x…

【VBA】【EXCEL】将某列内容横向粘贴到指定行

Sub CopyRowToColumn()On Error GoTo ErrorHandler 添加错误处理Application.ScreenUpdating FalseApplication.Calculation xlCalculationManualApplication.EnableEvents False 禁用事件处理Dim lastCol As LongDim lastRow As LongDim i As Long, colCount As LongDim …

JS进阶--JS听到了不灭的回响

作用域 作用域&#xff08;scope&#xff09;规定了变量能够被访问的“范围”&#xff0c;离开了这个“范围”变量便不能被访问 作用域分为局部和全局 局部作用域 局部作用域分为函数和块 那 什么是块作用域呢&#xff1f; 在 JavaScript 中使用 { } 包裹的代码称为代码块…

计算机网络 (26)互联网的路由选择协议

一、路由选择协议的基本概念 路由选择协议是计算机网络中用于确定数据包在网络中传输路径的一种协议。它帮助路由器构建和维护路由表&#xff0c;以便根据目的地址将数据包转发到正确的下一跳路由器。路由选择协议分为静态路由选择协议和动态路由选择协议两大类。 二、静态路由…

Spring项目创建流程及配置文件bean标签参数简介

1. 项目搭建流程 1. pom.xml中引入依赖Spring-webMVC <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><…

左神算法基础巩固--2

文章目录 稳定性选择排序冒泡排序插入排序归并排序快速排序堆排序 哈希表链表解题 稳定性 稳定性是指算法在排序过程中保持相等元素之间相对顺序的特性。具体来说&#xff0c;如果一个排序算法是稳定的&#xff0c;那么对于任意两个相等的元素&#xff0c;在排序前它们的相对顺…

UART串口数据分析

串口基础知识详细介绍&#xff1a; 该链接详细介绍了串并行、单双工、同异步、连接方式 https://blog.csdn.net/weixin_43386810/article/details/127156063 该文章将介绍串口数据的电平变化、波特率计算、脉宽计算以及数据传输量的计算。 捕获工具&#xff1a;逻辑分析仪&…

机器学习模型评估指标

模型的评估指标是衡量一个模型应用于对应任务的契合程度&#xff0c;常见的指标有&#xff1a; 准确率&#xff08;Accuracy&#xff09;: 正确预测的样本数占总样本数的比例。适用于类别分布均衡的数据集。 精确率&#xff08;Precision&#xff09;: 在所有被预测为正类的样…

面试题解,JVM中的“类加载”剖析

一、JVM类加载机制说一下 其中&#xff0c;从加载到初始化就是我们的类加载阶段&#xff0c;我们逐一来分析 加载 “加载 loading”是整个类加载&#xff08;class loading&#xff09;过程的一个阶段&#xff0c;加载阶段JVM需要完成以下 3 件事情&#xff1a; 1&#xff0…

腾讯云AI代码助手编程挑战赛-古诗词学习

一、作品介绍 在科技与文化深度交融的当下&#xff0c;“腾讯云 AI 代码助手编程挑战赛 - 每日古诗词” 宛如一颗璀璨的新星&#xff0c;闪耀登场。它绝非一场普通的赛事&#xff0c;而是一座连接编程智慧与古典诗词韵味的桥梁。 这项挑战赛以独特的视角&#xff0c;将每日古…

GelSight Mini视触觉传感器凝胶触头升级:增加40%耐用性,拓展机器人与触觉AI 应用边界

马萨诸塞州沃尔瑟姆-2025年1月6日-触觉智能技术领军企业Gelsight宣布&#xff0c;旗下Gelsight Mini视触觉传感器迎来凝胶触头的更新。经内部测试&#xff0c;新Gel凝胶触头耐用性提升40%&#xff0c;外观与触感与原凝胶触头保持一致。此次升级有效满足了客户在机器人应用中对设…

【C++入门】详解(上)

目录 &#x1f495;1.C中main函数内部———变量的访问顺序 &#x1f495;2.命名空间域namespace &#x1f495;3.命名空间域&#xff08;代码示例&#xff09;&#xff08;不要跳&#xff09; &#x1f495;4.多个命名空间域的内部重名 &#x1f495;5.命名空间域的展开 …

Ungoogled Chromium127 编译指南 MacOS篇(八)- 开始编译

1. 引言 完成了所有依赖包的安装后&#xff0c;我们终于来到了最关键的编译阶段。在开始编译之前&#xff0c;有一些重要的配置信息需要了解。本文将指导您完成整个编译过程。 2. 签名相关说明 虽然在我们的测试编译中不需要进行签名操作&#xff0c;但了解官方的签名要求仍…

使用uniapp 微信小程序一些好用的插件分享

总结一下自己在开发中遇见的一问题&#xff0c;通过引入组件可以快速的解决 1.zxz-uni-data-select 下拉框选择器(添加下拉框检索&#xff0c;多选功能&#xff0c;多选搜索功能&#xff0c;自定义 下拉框插件&#xff0c;使用这个的原因是因为 uniui uview 组件库下拉框太…

腾讯云AI代码助手编程挑战赛-有趣的冷知识分享

作品简介 有趣的冷知识这一编程主要用于对于小朋友的探索力的开发&#xff0c;让小朋友在一开始就对学习具有探索精神。在信息化时代下&#xff0c;会主动去学习自己认知以外的知识&#xff0c;同时丰富了眼界&#xff0c;开拓了新的知识。 技术架构 使用python语言的TK库…

使用 SQL 和表格数据进行问答和 RAG(7)—将表格数据(CSV 或 Excel 文件)加载到向量数据库(ChromaDB)中

将表格数据&#xff08;CSV 或 Excel 文件&#xff09;加载到向量数据库&#xff08;ChromaDB&#xff09;中。这里定义的类 PrepareVectorDBFromTabularData&#xff0c;它的主要功能是读取表格数据文件到DataFrame中、生成嵌入向量、并将这些数据存储在向量数据库的集合中&am…

攻防世界 wtf.sh-150

点进去&#xff0c;发现是一个类似于论坛的网站&#xff0c;并且对报错等做了处理 用御剑扫描一下 ​ 发现是php形式的文件&#xff0c;但点进去访问不了。看看wp&#xff0c;发现此题存在路径穿越漏洞&#xff0c;就是&#xff08;如果应用程序使用用户可控制的数据&#xff0…