Scala 容器类(二)

Seqs (Seq、IndexedSeq、LinearSeq)

Seq trait用于表示序列。序列,指的是一类具有一定长度的可迭代访问的对象,其中每个元素均带有一个从0开始计数的固定索引位置。
序列的操作如下:

索引和长度的操作 (apply、isDefinedAt、length、indices、lengthCompare。)

apply操作用于索引访问;因此,Seq[T]类型的序列也是一个以单个Int(索引下标)为参数、返回值类型为T的偏函数。换言之,Seq[T]继承自Partial Function[Int, T]。length方法是collection的size方法的别名。lengthCompare方法可以比较两个序列的长度,即便其中一个序列长度无限也可以处理。

索引检索操作(indexOf、lastIndexOf、indexofSlice、lastIndexOfSlice、indexWhere、lastIndexWhere、segmentLength、prefixLength)

返回等于给定值或满足某个谓词的元素的索引。

加法运算(+:,:+,padTo)

在序列的前面或者后面添加一个元素并作为新序列返回。

更新操作(updated,patch)

替换原序列的某些元素并作为一个新序列返回。

排序操作(sorted, sortWith, sortBy)

对序列元素进行排序。

反转操作(reverse, reverseIterator, reverseMap)

将序列中的元素以相反的顺序排列。

比较(startsWith, endsWith, contains, containsSlice, corresponds)

对两个序列进行比较,或者在序列中查找某个元素。

多集操作(intersect, diff, union, distinct)

对两个序列中的元素进行类似集合的操作,或者删除重复元素

Seq类的操作

操作 说明
索引和长度
xs(i) (或者xs apply i) xs的第i个元素
xs.indices xs的索引范围,从0到xs.length - 1
xs isDefinedAt i 测试xs.indices中是否包含i
xs.lengthCompare 如果xs的长度小于ys的长度,则返回-1。如果xs的长度大于ys的长度,则返回+1,如果它们长度相等,则返回0。即使其中一个序列是无限的,也可以使用此方法
索引搜寻
xs indexOf x 返回序列xs中等于x的第一个元素的索引(存在多种变体)
xs lastIndexOf x 返回序列xs中等于x的最后一个元素的索引(存在多种变体)
xs indexOfSlice ys 查找子序列ys,返回xs中匹配的第一个索引
xs lastIndexOfSlice ys 查找子序列ys,返回xs中匹配的倒数一个索引
xs indexWhere p xs序列中满足p的第一个元素。(有多种形式)
xs segmentLength (p, i) xs中,从xs(i)开始并满足条件p的元素的最长连续片段的长度
xs prefixLength p xs序列中满足p条件的先头元素的最大个数
加法:
x +: xs 由序列xs的前方添加x所得的新序列
xs :+ x 由序列xs的后方追加x所得的新序列
xs padTo (len, x) 在xs后方追加x,直到长度达到len后得到的序列
更新:
xs patch (i, ys, r) 将xs中第i个元素开始的r个元素,替换为ys所得的序列
xs updated (i, x) 将xs中第i个元素替换为x后所得的xs的副本
xs(i) = x (或写作 xs.update(i, x),仅适用于可变序列)将xs序列中第i个元素修改为x
排序:
xs.sorted 通过使用xs中元素类型的标准顺序,将xs元素进行排序后得到的新序列
xs sortWith lt 将lt作为比较操作,并以此将xs中的元素进行排序后得到的新序列
xs sortBy f 将序列xs的元素进行排序后得到的新序列。参与比较的两个元素各自经f函数映射后得到一个结果,通过比较它们的结果来进行排序
反转
xs.reverseIterator 产生序列xs中元素的反序迭代器
xs reverseMap f 以xs的相反顺序,通过f映射xs序列中的元素得到的新序列
比较
xs startsWith ys 测试序列xs是否以序列ys开头(存在多种形式)
xs endsWith ys 测试序列xs是否以序列ys结束(存在多种形式)
xs containsSlice ys 测试xs序列中是否存在一个与ys相同的连续子序列
(xs corresponds ys)(p) 测试序列xs与序列ys中对应的元素是否满足二元的判断式p
多集操作
xs intersect ys 序列xs和ys的交集,并保留序列xs中的顺序
xs diff ys 序列xs和ys的差集,并保留序列xs中的顺序
xs union ys 并集;同xs ++ ys
xs.distinct 不含重复元素的xs的子序列

trait Seq 具有两个subtrait LinearSeq和IndexedSeq。
他们提供不同的性能特点:线性序列具有高效的 head 和 tail 操作,而索引序列具有高效的apply, length, 和 (如果可变) update操作。

Vector 类提供一个在索引访问和线性访问之间有趣的折中。它同时具有高效的恒定时间的索引开销,和恒定时间的线性访问开销。正因为如此,对于混合访问模式,vector是一个很好的基础。

因为Seq的子类包含List,所以这里用List作为例子对上述操作做一个简单的例子实现。

REPL:

//索引和长度
scala> val a = List(1,2,3,4,5,6)
a: List[Int] = List(1, 2, 3, 4, 5, 6)

scala> a isDefinedAt 0
res0: Boolean = true

scala> val b = List(2,3,4)
b: List[Int] = List(2, 3, 4)

scala> a.lengthCompare(b)
res1: Int = 1

scala> a.indices
res2: scala.collection.immutable.Range = Range 0 until 6

//索引搜索
scala> a.lastIndexOf(7)
res0: Int = -1 

scala> a.lastIndexOf(1)
res1: Int = 0

scala> val b = List(2,3,4)
b: List[Int] = List(2, 3, 4)

scala> a.indexOfSlice(b)
res2: Int = 1

scala> a.lastIndexOfSlice(b)
res3: Int = 1

scala> a.indexWhere(_>3)
res6: Int = 3

scala> a.segmentLength(_ >= 2 ,2)  //这里存在疑问
res9: Int = 4

// 加法
scala> a.padTo(10,1)
res12: List[Int] = List(1, 2, 3, 4, 5, 6, 1, 1, 1, 1)

//更新
scala> a.patch(3,List("a","b"),1)
res14: List[Any] = List(1, 2, 3, a, b, 5, 6)

scala> a.updated(0,2)
res16: List[Int] = List(2, 2, 3, 4, 5, 6)

//排序
scala> val a = List(2,1,5,3,6,0)
a: List[Int] = List(2, 1, 5, 3, 6, 0)

scala> a.sorted
res23: List[Int] = List(0, 1, 2, 3, 5, 6)

val words = "The quick brown fox jumped over the lazy dog".split(' ')
// this works because scala.Ordering will implicitly provide an Ordering[Tuple2[Int, Char]]
words.sortBy(x => (x.length, x.head))
res0: Array[String] = Array(The, dog, fox, the, lazy, over, brown, quick, jumped)

scala> a.sortBy(_.intValue)
res31: List[Int] = List(0, 1, 2, 3, 5, 6)

scala> a
res36: List[Int] = List(2, 1, 5, 3, 6, 0)

scala> a.reverseIterator
res32: Iterator[Int] = <iterator>

scala> res32.next()
res33: Int = 0

scala> res32.next()
res34: Int = 6

scala> res32.next()
res35: Int = 3

scala> a.containsSlice(List(2,1,5))
res37: Boolean = true

//多集操作 
scala> a.intersect(b)
res38: List[Int] = List(2, 3)

scala> a.diff(b)
res40: List[Int] = List(1, 5, 6, 0)


Buffers

Buffers是可变序列一个重要的种类,可以更新元素并允许元素的插入、删除以及高效添加元素。

Buffer类的操作

操作 说明
加法
buf += x 将元素x追加到buffer,并将buf自身作为结果返回
buf += (x, y, z) 将给定的元素追加到buffer
buf ++= xs 将xs中的所有元素追加到buffer
x +=: buf 将元素x添加到buffer的前方
xs ++=: buf 将xs中的所有元素都添加到buffer的前方
buf insert (i, x) 将元素x插入到buffer中索引为i的位置
buf insertAll (i, xs) 将xs的所有元素都插入到buffer中索引为i的位置
移除
buf -= x 将元素x从buffer中移除
buf remove i 将buffer中索引为i的元素移除
buf remove (i, n) 将buffer中从索引i开始的n个元素移除
buf trimStart n 移除buffer中的前n个元素
buf trimEnd n 移除buffer中的后n个元素
buf.clear() 移除buffer中的所有元素
克隆
buf.clone 与buf具有相同元素的新buffer

以ArrayBuffer为例

REPL:

//加法
scala> val arrbuffer = scala.collection.mutable.ArrayBuffer(2,4,6,7)
arrbuffer: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(2, 4, 6, 7)

scala> arrbuffer.insert(2,5)

scala> arrbuffer
res44: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(2, 4, 5, 6, 7)

scala> val arr = Array(10,11,12,13)
arr: Array[Int] = Array(10, 11, 12, 13)

scala> arrbuffer.insertAll(4,arr)

scala> arrbuffer
res49: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(2, 4, 5, 6, 10, 11, 12, 13, 7)
//移除
scala> arrbuffer.trimStart(3)

scala> arrbuffer
res51: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(6, 10, 11, 12, 13, 7)

scala> arrbuffer.trimEnd(2)

scala> arrbuffer
res53: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(6, 10, 11, 12)
//加法的前加
scala> 10 +=: arrbuffer
res55: arrbuffer.type = ArrayBuffer(10, 6, 10, 11, 12)

scala> Array(1,2,3) ++=: arrbuffer
res56: arrbuffer.type = ArrayBuffer(1, 2, 3, 10, 6, 10, 11, 12)

//克隆
scala> arrbuffer.clone
res57: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 10, 6, 10, 11, 12)
posted @   憨憨的  阅读(295)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
点击右上角即可分享
微信分享提示