Scala Mutable 和 Immutable 集合怎么用?区别和选择指南

文章导读
Previous Quiz Next Scala 的集合库位于 scala.collection 包下。Scala 中的集合是高效存储、检索和操作对象组的基础。有两种类型的集合:可变和不可变。本章将介绍这两种集合。
📋 目录
  1. 可变集合
  2. 不可变集合
  3. 可变集合与不可变集合的区别
A A

Scala - 可变和不可变集合



Previous
Quiz
Next

Scala 的集合库位于 scala.collection 包下。Scala 中的集合是高效存储、检索和操作对象组的基础。有两种类型的集合:可变和不可变。本章将介绍这两种集合。

可变集合

即使在声明后,你也可以更新和修改可变类型的集合。你可以就地更新可变集合,因此无需为这些更新创建其他集合。可变集合位于 scala.collection.mutable 中。因此,在处理可变集合时,你需要导入这个库。当你需要频繁更新集合时,使用可变集合。

示例包括:ListBuffer、HashSet、HashMap、ArrayBuffer、Queue、Stack。

声明可变集合

以下是在 Scala 中声明各种可变集合的语法 -

语法

import scala.collection.mutable.ListBuffer
import scala.collection.mutable.HashSet
import scala.collection.mutable.HashMap

val mutableList: ListBuffer[String] = ListBuffer("Apple", "Banana", "Cherry")
val mutableSet: HashSet[String] = HashSet("Apple", "Banana", "Cherry")
val mutableMap: HashMap[String, String] = HashMap
   ("red" -> "#FF0000", "green" -> "#00FF00", "blue" -> "#0000FF")

注意,必须导入它们的库,否则将无法编译。

示例

下面是一个示例程序,展示如何创建、初始化和处理可变集合

import scala.collection.mutable.ListBuffer
import scala.collection.mutable.HashSet
import scala.collection.mutable.HashMap

object Demo {
   def main(args: Array[String]) = {
      val mutableList: ListBuffer[String] = ListBuffer("Apple", "Banana", "Cherry")
      val mutableSet: HashSet[String] = HashSet("Apple", "Banana", "Cherry")
      val mutableMap: HashMap[String, String] = HashMap
         ("red" -> "#FF0000", "green" -> "#00FF00", "blue" -> "#0000FF")

      // 打印集合
      println(mutableList)
      println(mutableSet)
      println(mutableMap)

      // 修改集合(就地修改)
      mutableList += "Grapes"
      mutableSet += "Grapes"
      mutableMap += ("yellow" -> "#FFFF00")

      // 打印修改后的集合
      println(mutableList)
      println(mutableSet)
      println(mutableMap)
   }
}

将上述程序保存为 Demo.scala。使用以下命令编译和执行该程序。

命令

> scalac Demo.scala
> scala Demo

输出

ListBuffer(Apple, Banana, Cherry)
Set(Apple, Banana, Cherry)
Map(red -> #FF0000, green -> #00FF00, blue -> #0000FF)
ListBuffer(Apple, Banana, Cherry, Grapes)
Set(Apple, Banana, Cherry, Grapes)
Map(red -> #FF0000, green -> #00FF00, blue -> #0000FF, yellow -> #FFFF00)

不可变集合

一旦创建了不可变类型的集合,就不能更新和修改它们。如果尝试向不可变集合添加、删除或更新元素,编译器将返回一个新的集合。原始集合将保持不变。不可变集合位于 scala.collection.immutable 中。因此,在处理不可变集合时,需要导入这个库。

示例包括:List、Set、Map、Vector、Queue、Stack、Range、Option、Tuple、Iterator。

声明不可变集合

以下是在 Scala 中声明各种不可变集合的语法 -

语法

import scala.collection.immutable.List
import scala.collection.immutable.Set
import scala.collection.immutable.Map

val immutableList: List[String] = List("Apple", "Banana", "Cherry")
val immutableSet: Set[String] = Set("Apple", "Banana", "Cherry")
val immutableMap: Map[String, String] = Map
   ("red" -> "#FF0000", "green" -> "#00FF00", "blue" -> "#0000FF")

由于这些集合默认就是不可变的,即使不导入它们的不可变集合库,也能正常工作,就像这样 -

val immutableList: List[String] = List("Apple", "Banana", "Cherry")
val immutableSet: Set[String] = Set("Apple", "Banana", "Cherry")
val immutableMap: Map[String, String] = Map
   ("red" -> "#FF0000", "green" -> "#00FF00", "blue" -> "#0000FF")

示例

object Demo {
   def main(args: Array[String]) = {
      val immutableList: List[String] = List("Apple", "Banana", "Cherry")
      val immutableSet: Set[String] = Set("Apple", "Banana", "Cherry")
      val immutableMap: Map[String, String] = Map
         ("red" -> "#FF0000", "green" -> "#00FF00", "blue" -> "#0000FF")

      // 打印集合
      println(immutableList)
      println(immutableSet)
      println(immutableMap)

      // 尝试修改集合(将返回新的集合)
      val newList = immutableList :+ "Grapes"
      val newSet = immutableSet + "Grapes"
      val newMap = immutableMap + ("yellow" -> "#FFFF00")

      // 打印新的集合
      println(newList)
      println(newSet)
      println(newMap)
   }
}

将上述程序保存为 Demo.scala。使用以下命令编译和执行该程序。

命令

> scalac Demo.scala
> scala Demo

输出

List(Apple, Banana, Cherry)
Set(Apple, Banana, Cherry)
Map(red -> #FF0000, green -> #00FF00, blue -> #0000FF)
List(Apple, Banana, Cherry, Grapes)
Set(Apple, Banana, Cherry, Grapes)
Map(red -> #FF0000, green -> #00FF00, blue -> #0000FF, yellow -> #FFFF00)

可变集合与不可变集合的区别

特性 可变集合 不可变集合
可修改性 创建后可以修改。 创建后不可修改。
线程安全性 并非天生线程安全。 天生线程安全。
性能 适用于频繁更新和大容量数据集。 适用于函数式编程和线程安全操作。
内存消耗 由于可能的内部重新分配,可能使用更多内存。 由于结构不被修改,通常使用更少内存。
常见用例 实时数据处理、性能关键应用。 函数式编程、并发应用。
示例 ListBuffer, HashSet, HashMap, ArrayBuffer, Queue, Stack List, Set, Map, Vector, Queue, Stack, Range, Option, Tuple, Iterator