五-4, Scala 队列,并行集合

1. Scala队列

1,1 Scala Queen 定义

  • Scala 同 Java 一样,已经直接给出了 Queue 的实现。它本质上是一个有序列表,在底层可以使用数组或者链表去实现。
  • Queue 显然遵循先入先出的原则。Scala 同时给出了对于队列的 mutable 实现和 immutable 实现。对于不可变队列,进行操作后会返回新的队列;对于可变队列,进队出队操作是在原先的队列中进行的。
//加上前缀来明确声明使用的是可变队列还是不可变队列。
//apply方法实现
mutable.Queue[Any](1,2,3,4,5,6,7)

//new调用构造器来实现
new mutable.Queue[Any]()

1.2 在Queen中添加新元素

  • 可变的 Queue 支持使用 +=++=操作实现类似在 ListBuffer 中介绍过的功能,这里直接以代码形式给出,并在注释上附带上一些要点
//+= 可以用于添加单个元素。
queue += 8

//+= 会将一个 List 整体当作一个元素加到队列。不过你的 queue 未必支持将 List 整体放入其中,因为这可能其实并不是你的本意。
//如果你希望的是添加 ListBuffer 内的每个元素,那么应该使用 ++= 方法。
queue += ListBuffer[String]("a","b","c")

//++= 和 += 的区别是,它会将队列里的元素按次序全部追加到队列中,而不是添加列表本身。
queue ++= ListBuffer[Int](8,9,10)

1.3 Queen的进队和出队

  • Queue 还提供enqueue方法进队,以及dequeue出队方法,可变队列会在原队列中修改,不可变队列会返回新的队列。
//apply方法实现
val queue: mutable.Queue[Any] = mutable.Queue[Any](1,2,3,4,5,6,7)

//运算符方式追加元素
queue += 8

//查看队列头
println(s"queue head : ${queue.head}")

//弹出首个元素
val first: Any = queue.dequeue()
print(s"popped element: $first")

//再次查看队列头
println(s"queue head : ${queue.head}")

  • 另外,可以通过queue.head来查看队列头的元素内容,或者通过queue.last来查看队列尾部元素内容(但都不弹出)
    Queue 还提供一个独特的方法:queen.tail。故名思意,就是返回尾部。在队列中,除了第一个 head 元素以外都可称作尾部(而不是指最后一个元素)。这个方法弹出首元素,然后将剩下的元素排列成一个新队列返回。更通俗点说,enqueue是取 “头” ,则 tail 是去掉 “头” 之后剩下的 “躯干” 部分。
//查看原队列头部的元素。
print(ints.head)

//tail方法会将原先的队列去head元素之后返回新队列。
val newInts : mutable.Queue[Int] = ints.tail

//打印新生成的队列。
println(newInts)

//原来的队列没有变化。
println(ints)
  • tail方法的返回值也是一个队列,因此可以级联调用该方法,让它一次性弹出多个元素。
val ints: mutable.Queue[Int] = mutable.Queue[Int](1,2,3,4,5)

//tail方法可以级联调用,因为该方法的返回值也是一个队列。
val newInts : mutable.Queue[Int] = ints.tail.tail.tail.tail

//去掉4个头元素之后,这个队列只剩下5。
print(newInts)

  • 使用下标访问的方式越过 FIFO 的原则直接访问元素其实也完全没有问题,因为Scala 将 Queue 划分到了线性序列中。不过既然使用了队列,就应该尽量按照队列先进先出的原则去使用它。
//get the 2th element of the queue?
println(ints(1))   //OK.  queue is indeed a sequence.

2. 并行集合

  • Scala 为了充分使用多核 CPU,提供了并行集合(有别于前面的串行集合),用于多核环境的并行计算。
object TestPar {
	def main(args: Array[String]): Unit = {
		val  result1  =  (0  to  100).map{case  _  =>
Thread.currentThread.getName}
// par 标志着此段程序做并行计算, 线程id大都是不相同的
		val  result2  =  (0  to  100).par.map{case  _  =>
Thread.currentThread.getName}
		println(result1)
		println(result2)
	}
}
posted @   青松城  阅读(80)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示