Scala 集合 - 快速指南


Scala 集合 - 概述

Scala拥有一套丰富的集合库。集合是事物的容器。这些容器可以是有序的、线性的项目集,如列表、元组、选项、映射等。这些集合可以具有任意数量的元素,或者限制为零个或一个元素(例如,选项)。

集合可能是严格的,也可能是惰性的。惰性集合的元素在被访问之前可能不会消耗内存,例如Ranges。此外,集合可以是可变的(引用的内容可以更改)或不可变的(引用引用的内容永远不会更改)。请注意,不可变集合可能包含可变项。

对于某些问题,可变集合效果更好,而对于其他问题,不可变集合效果更好。如有疑问,最好从不可变集合开始,如果需要可变集合,稍后再更改它。

本章重点介绍最常用的集合类型以及对这些集合最常用的操作。

先生编号 带有描述的集合
1

Scala 列表

Scala 的 List[T] 是 T 类型的链表。

2

Scala 集

集合是相同类型的成对不同元素的集合。

3

斯卡拉地图

Map 是键/值对的集合。任何值都可以根据其键来检索。

4

Scala 元组

与数组或列表不同,元组可以保存不同类型的对象。

5

Scala 选项

Option[T] 为给定类型的零个或一个元素提供容器。

6

Scala 迭代器

迭代器不是集合,而是一种逐个访问集合元素的方法。

Scala 集合 - 环境设置

Scala 可以安装在任何 UNIX 风格或基于 Windows 的系统上。在开始在计算机上安装 Scala 之前,您的计算机上必须安装 Java 1.8 或更高版本。

请按照以下步骤安装 Scala。

第 1 步:验证您的 Java 安装

首先,您需要在系统上安装 Java 软件开发工具包 (SDK)。要验证这一点,请根据您正在使用的平台执行以下两个命令中的任意一个。

如果 Java 安装已正确完成,那么它将显示 Java 安装的当前版本和规范。下表给出了示例输出。

平台 命令 样本输出
Windows

打开命令控制台并输入 -

\>java-版本

Java版本“1.8.0_31”

Java (TM) SE 运行时

环境(版本1.8.0_31-b31)

Java Hotspot (TM) 64 位服务器

VM(内部版本 25.31-b07,混合模式)

Linux

打开命令终端并输入 -

$java-版本

Java版本“1.8.0_31”

打开JDK运行环境(rhel-2.8.10.4.el6_4-x86_64)

打开 JDK 64 位服务器 VM(内部版本 25.31-b07,混合模式)

我们假设本教程的读者在其系统上安装了 Java SDK 版本 1.8.0_31。

如果您没有 Java SDK,请从https://www.oracle.com/technetwork/java/javase/downloads/index.html下载其当前版本并安装。

第 2 步:设置 Java 环境

将环境变量 JAVA_HOME 设置为指向计算机上安装 Java 的基本目录位置。例如,

先生编号 平台及描述
1

Windows

将 JAVA_HOME 设置为 C:\ProgramFiles\java\jdk1.8.0_31

2

Linux

导出 JAVA_HOME=/usr/local/java-current

将 Java 编译器位置的完整路径附加到系统路径。

先生编号 平台及描述
1

Windows

将字符串“C:\Program Files\Java\jdk1.8.0_31\bin”附加到系统变量 PATH 的末尾。

2

Linux

导出 PATH=$PATH:$JAVA_HOME/bin/

如上所述,从命令提示符处执行命令java -version 。

第三步:安装Scala

您可以从www.scala-lang.org/downloads下载 Scala 。在编写本教程时,我下载了“scala-2.13.1-installer.jar”。确保您具有管理员权限才能继续。现在,在命令提示符下执行以下命令 -

平台 命令与输出 描述
Windows

\>java -jar scala-2.13.1-installer.jar\>

此命令将显示一个安装向导,它将指导您在 Windows 计算机上安装 Scala。在安装过程中,它会询问许可协议,只需接受它,然后它会询问 Scala 的安装路径。我选择默认给定路径“C:\Program Files\Scala”,您可以根据自己的方便选择合适的路径。

Linux

命令-

$java -jar scala-2.13.1-installer.jar

输出-

欢迎安装Scala 2.13.1!

主页位于 - http://Scala-lang.org/

按 1 继续,按 2 退出,按 3 重新显示

1.................................................

[开始拆箱]

[ 处理包:软件包安装(1/1) ]

[ 开箱完毕 ]

[控制台安装完成]

在安装过程中,它会询问许可协议,接受它,输入 1,它会询问 Scala 的安装路径。我输入的是/usr/local/share,你可以根据自己的方便选择合适的路径。

最后,打开一个新的命令提示符并输入Scala -version并按 Enter。您应该看到以下内容 -

平台 命令 输出
Windows

\>scala-版本

Scala 代码运行器版本 2.13.1 — 版权所有 2002-2019,LAMP/EPFL 和 Lightbend, Inc.

Linux

$scala-版本

Scala 代码运行器版本 2.13.1 — 版权所有 2002-2019,LAMP/EPFL 和 Lightbend, Inc.tut

Scala 集合 - 数组

Scala 提供了一种数据结构,即数组,它存储相同类型元素的固定大小的顺序集合。数组用于存储数据的集合,但将数组视为相同类型的变量的集合通常更有用。

您可以声明一个数组变量(例如numbers)并使用numbers[0]、numbers[1]和...、numbers[99]来表示,而不是声明单个变量(例如number0、number1、...和number99)个体变量。本教程介绍如何声明数组变量、创建数组以及使用索引变量处理数组。数组第一个元素的索引是数字零,最后一个元素的索引是元素总数减一。

声明数组变量

要在程序中使用数组,必须声明一个变量来引用该数组,并且必须指定该变量可以引用的数组类型。

以下是声明数组变量的语法。

句法

var z:Array[String] = new Array[String](3)

or

var z = new Array[String](3)

此处,z 被声明为最多可容纳三个元素的字符串数组。可以将值分配给各个元素或访问各个元素,这可以通过使用如下命令来完成 -

命令

z(0) = "Zara"; z(1) = "Nuha"; z(4/2) = "Ayan"

这里,最后一个示例表明,一般来说,索引可以是产生整数的任何表达式。还有另一种定义数组的方法 -

var z = Array("Zara", "Nuha", "Ayan")

下图代表一个数组myList。这里,myList保存十个双精度值,索引从 0 到 9。

斯卡拉数组

处理数组

在处理数组元素时,我们经常使用循环控制结构,因为数组中的所有元素都具有相同的类型并且数组的大小是已知的。

下面是一个示例程序,展示了如何创建、初始化和处理数组 -

例子

object Demo {
   def main(args: Array[String]) {
      var myList = Array(1.9, 2.9, 3.4, 3.5)
      
      // Print all the array elements
      for ( x <- myList ) {
         println( x )
      }
      // Summing all elements
      var total = 0.0;
      for ( i <- 0 to (myList.length - 1)) {
         total += myList(i);
      }
      println("Total is " + total);
      // Finding the largest element
      var max = myList(0);
      for ( i <- 1 to (myList.length - 1) ) {
         if (myList(i) > max) max = myList(i);
      }
      println("Max is " + max);
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

1.9
2.9
3.4
3.5
Total is 11.7
Max is 3.5

Scala并不直接支持各种数组操作,而是提供了各种方法来处理任意维度的数组。如果你想使用不同的方法,那么需要导入Array._包。

Scala 集合 - 多维数组

在许多情况下,您需要定义和使用多维数组(即元素为数组的数组)。例如,矩阵和表是可以实现为二维数组的结构示例。

以下是定义二维数组的示例 -

var myMatrix = ofDim[Int](3,3)

这是一个具有三个元素的数组,每个元素都是具有三个元素的整数数组。

尝试以下示例程序来处理多维数组 -

例子

import Array._
object Demo {
   def main(args: Array[String]) {
      var myMatrix = ofDim[Int](3,3)
      // build a matrix
      for (i <- 0 to 2) {
         for ( j <- 0 to 2) {
            myMatrix(i)(j) = j;
         }
      }
      // Print two dimensional array
      for (i <- 0 to 2) {
         for ( j <- 0 to 2) {
            print(" " + myMatrix(i)(j));
         }
         println();
      }
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

0 1 2
0 1 2
0 1 2

Scala 集合 - 带范围的数组

使用 range() 方法生成一个包含给定范围内递增整数序列的数组。您可以使用最终参数作为创建序列的步骤;如果不使用最终参数,则步骤将假定为 1。

我们以创建一个范围为(10, 20, 2)的数组为例: 意思是创建一个元素在10到20之间且范围差为2的数组。数组中的元素为10, 12, 14, 16, 18 。

另一个例子:范围 (10, 20)。这里没有给出范围差异,因此默认情况下假设 1 个元素。它创建一个数组,其中元素在 10 到 20 之间,范围差为 1。数组中的元素为 10、11、12、13、...和 ​​19。

以下示例程序展示了如何创建具有范围的数组。

例子

import Array._
object Demo {
   def main(args: Array[String]) {
      var myList1 = range(10, 20, 2)
      var myList2 = range(10,20)
      // Print all the array elements
      for ( x <- myList1 ) {
         print( " " + x )
      }
      println()
      for ( x <- myList2 ) {
         print( " " + x )
      }
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

10 12 14 16 18
10 11 12 13 14 15 16 17 18 19

Scala 集合 - ArrayBuffer

Scala 提供了一个数据结构 ArrayBuffer 它可以在初始大小不足时更改大小。由于数组的大小是固定的,并且数组中不能占用更多的元素,因此ArrayBuffer是大小灵活的数组的替代方案。

ArrayBuffer 在内部维护一个当前大小的数组来存储元素。添加新元素时,会检查大小。如果底层数组已满,则会创建一个新的更大数组,并将所有元素复制到更大数组中。

声明 ArrayBuffer 变量

以下是声明 ArrayBuffer 变量的语法。

句法

var z = ArrayBuffer[String]()

这里,z 被声明为字符串数组缓冲区,最初为空。可以使用如下命令添加值 -

命令

z += "Zara";
z += "Nuha";
z += "Ayan";

处理数组缓冲区

下面是一个示例程序,展示了如何创建、初始化和处理 ArrayBuffer -

例子

import scala.collection.mutable.ArrayBuffer 
object Demo {
   def main(args: Array[String]) = {
      var myList = ArrayBuffer("Zara","Nuha","Ayan")
      println(myList);
      // Add an element
      myList += "Welcome";
      // Add two element
      myList += ("To", "Tutorialspoint");
      println(myList);
      // Remove an element
      myList -= "Welcome";
      // print second element
      println(myList(1));
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

ArrayBuffer(Zara, Nuha, Ayan)
ArrayBuffer(Zara, Nuha, Ayan, Welcome, To, Tutorialspoint)
Nuha

Scala 集合 - 列表

Scala 列表与数组非常相似,这意味着列表中的所有元素都具有相同的类型,但有两个重要的区别。首先,列表是不可变的,这意味着列表的元素不能通过赋值来更改。其次,列表表示链表,而数组是平面的。

具有 T 类型元素的列表的类型写为List[T]

尝试以下示例,这里是为各种数据类型定义的一些列表。

// List of Strings
val fruit: List[String] = List("apples", "oranges", "pears")
// List of Integers
val nums: List[Int] = List(1, 2, 3, 4)
// Empty List.
val empty: List[Nothing] = List()
// Two dimensional list
val dim: List[List[Int]] = List(
   List(1, 0, 0),
   List(0, 1, 0),
   List(0, 0, 1)
)

所有列表都可以使用两个基本构建块来定义:尾部Nil::,其发音为cons。Nil 也代表空列表。所有上述列表都可以定义如下。

// List of Strings
val fruit = "apples" :: ("oranges" :: ("pears" :: Nil))
// List of Integers
val nums = 1 :: (2 :: (3 :: (4 :: Nil)))
// Empty List.
val empty = Nil
// Two dimensional list
val dim = (1 :: (0 :: (0 :: Nil))) ::
   (0 :: (1 :: (0 :: Nil))) ::
   (0 :: (0 :: (1 :: Nil))) :: Nil

列表的基本操作

列表上的所有操作都可以用以下三种方法来表示。

先生编号 方法与说明
1

此方法返回列表的第一个元素。

2

尾巴

此方法返回一个包含除第一个元素之外的所有元素的列表。

3

是空的

如果列表为空,则此方法返回 true,否则返回 false。

下面的例子展示了如何使用上述方法。

例子

object Demo {
   def main(args: Array[String]) {
      val fruit = "apples" :: ("oranges" :: ("pears" :: Nil))
      val nums = Nil
      println( "Head of fruit : " + fruit.head )
      println( "Tail of fruit : " + fruit.tail )
      println( "Check if fruit is empty : " + fruit.isEmpty )
      println( "Check if nums is empty : " + nums.isEmpty )
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

Head of fruit : apples
Tail of fruit : List(oranges, pears)
Check if fruit is empty : false
Check if nums is empty : true

连接列表

您可以使用:::运算符或List.:::()方法或List.concat()方法添加两个或多个列表。请查找下面给出的示例 -

例子

object Demo {
   def main(args: Array[String]) {
      val fruit1 = "apples" :: ("oranges" :: ("pears" :: Nil))
      val fruit2 = "mangoes" :: ("banana" :: Nil)
      // use two or more lists with ::: operator
      var fruit = fruit1 ::: fruit2
      println( "fruit1 ::: fruit2 : " + fruit )
      // use two lists with Set.:::() method
      fruit = fruit1.:::(fruit2)
      println( "fruit1.:::(fruit2) : " + fruit )
      // pass two or more lists as arguments
      fruit = List.concat(fruit1, fruit2)
      println( "List.concat(fruit1, fruit2) : " + fruit  )
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

fruit1 ::: fruit2 : List(apples, oranges, pears, mangoes, banana)
fruit1.:::(fruit2) : List(mangoes, banana, apples, oranges, pears)
List.concat(fruit1, fruit2) : List(apples, oranges, pears, mangoes, banana)

创建统一列表

您可以使用List.fill()方法创建一个由零个或多个相同元素的副本组成的列表。尝试以下示例程序。

例子

object Demo {
   def main(args: Array[String]) {
      val fruit = List.fill(3)("apples") // Repeats apples three times.
      println( "fruit : " + fruit  )
      val num = List.fill(10)(2)         // Repeats 2, 10 times.
      println( "num : " + num  )
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

fruit : List(apples, apples, apples)
num : List(2, 2, 2, 2, 2, 2, 2, 2, 2, 2)

将函数制成表格

在对列表进行制表之前,您可以使用函数和List.tabulate()方法来应用列表中的所有元素。它的参数与 List.fill 的参数类似:第一个参数 list 给出要创建的列表的维度,第二个参数描述列表的元素。唯一的区别是元素不是固定的,而是根据函数计算的。

尝试以下示例程序。

例子

object Demo {
   def main(args: Array[String]) {
      // Creates 5 elements using the given function.
      val squares = List.tabulate(6)(n => n * n)
      println( "squares : " + squares  )
      val mul = List.tabulate( 4,5 )( _ * _ )      
      println( "mul : " + mul  )
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

squares : List(0, 1, 4, 9, 16, 25)
mul : List(List(0, 0, 0, 0, 0), List(0, 1, 2, 3, 4), 
   List(0, 2, 4, 6, 8), List(0, 3, 6, 9, 12))

反转列表顺序

您可以使用List.reverse方法来反转列表中的所有元素。以下示例显示了用法。

例子

object Demo {
   def main(args: Array[String]) {
      val fruit = "apples" :: ("oranges" :: ("pears" :: Nil))
      println( "Before reverse fruit : " + fruit )
      println( "After reverse fruit : " + fruit.reverse )
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

Before reverse fruit : List(apples, oranges, pears)
After reverse fruit : List(pears, oranges, apples)

Scala 集合 - ListBuffer

Scala 提供了一种数据结构ListBuffer,在添加/删除列表中的元素时,它比 List 更高效。它提供了在列表中添加元素的方法。

声明 ListBuffer 变量

以下是声明 ListBuffer 变量的语法。

句法

var z = ListBuffer[String]()

这里,z 被声明为字符串列表缓冲区,最初为空。可以使用如下命令添加值 -

命令

z += "Zara";
z += "Nuha";
z += "Ayan";

处理列表缓冲区

下面是一个示例程序,展示了如何创建、初始化和处理 ListBuffer -

例子

import scala.collection.mutable.ListBuffer 
object Demo {
   def main(args: Array[String]) = {
      var myList = ListBuffer("Zara","Nuha","Ayan")
      println(myList);
      // Add an element
      myList += "Welcome";
      // Add two element
      myList += ("To", "Tutorialspoint");
      println(myList);
      // Remove an element
      myList -= "Welcome";
      // print second element
      println(myList(1));
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

ListBuffer(Zara, Nuha, Ayan)
ListBuffer(Zara, Nuha, Ayan, Welcome, To, Tutorialspoint)
Nuha

Scala 集合 - ListSet

Scala Set 是同一类型的成对不同元素的集合。换句话说,Set 是不包含重复元素的集合。ListSet 实现不可变集并使用列表结构。存储元素时保留元素插入顺序。

声明 ListSet 变量

以下是声明 ListSet 变量的语法。

句法

var z : ListSet[String] = ListSet("Zara","Nuha","Ayan")

这里,z 被声明为具有三个成员的字符串列表集。可以使用如下命令添加值 -

命令

var myList1: ListSet[String] = myList + "Naira";

处理列表集

下面是一个示例程序,展示了如何创建、初始化和处理 ListSet -

例子

import scala.collection.immutable.ListSet
object Demo {
   def main(args: Array[String]) = {
      var myList: ListSet[String] = ListSet("Zara","Nuha","Ayan");
      // Add an element
      var myList1: ListSet[String] = myList + "Naira";
      // Remove an element
      var myList2: ListSet[String] = myList - "Nuha";
      // Create empty set
      var myList3: ListSet[String] = ListSet.empty[String];
      println(myList);
      println(myList1);
      println(myList2);
      println(myList3);	  
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

ListSet(Zara, Nuha, Ayan)
ListSet(Zara, Nuha, Ayan, Naira)
ListSet(Zara, Ayan)
ListSet()

Scala 集合-矢量

Scala Vector 是一种通用的不可变数据结构,其中的元素可以随机访问。它通常用于大量数据的收集。

声明向量变量

以下是声明 Vector 变量的语法。

句法

var z : Vector[String] = Vector("Zara","Nuha","Ayan")

这里,z 被声明为具有三个成员的字符串向量。可以使用如下命令添加值 -

命令

var vector1: Vector[String] = z + "Naira";

处理向量

下面是一个示例程序,展示了如何创建、初始化和处理 Vector -

例子

import scala.collection.immutable.Vector
object Demo {
   def main(args: Array[String]) = {
      var vector: Vector[String] = Vector("Zara","Nuha","Ayan");
      // Add an element
      var vector1: Vector[String] = vector :+ "Naira";
      // Reverse an element
      var vector2: Vector[String] = vector.reverse;
      // sort a vector
      var vector3: Vector[String] = vector1.sorted;
      println(vector);
      println(vector1);
      println(vector2);
      println(vector3);	  
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

Vector(Zara, Nuha, Ayan)
Vector(Zara, Nuha, Ayan, Naira)
Vector(Ayan, Nuha, Zara)
Vector(Ayan, Naira, Nuha, Zara)

Scala 集合 - 集

Scala Set 是同一类型的成对不同元素的集合。换句话说,Set 是不包含重复元素的集合。Set 有两种,不可变的可变的。可变对象和不可变对象之间的区别在于,当对象不可变时,对象本身不能更改。

默认情况下,Scala 使用不可变集。如果要使用可变 Set,则必须显式导入scala.collection.mutable.Set类。如果您想在同一个集合中同时使用可变集和不可变集,那么您可以继续将不可变集称为Set,但可以将可变集称为mutable.Set

以下是声明不可变集的方法 -

句法

// Empty set of integer type
var s : Set[Int] = Set()
// Set of integer type
var s : Set[Int] = Set(1,3,5,7)

or 

var s = Set(1,3,5,7)

在定义空集时,类型注释是必要的,因为系统需要为变量分配具体类型。

片场基本操作

集合上的所有运算都可以用以下三种方法表示 -

先生编号 方法与说明
1

此方法返回集合的第一个元素。

2

尾巴

此方法返回一个由除第一个元素之外的所有元素组成的集合。

3

是空的

如果集合为空,则此方法返回 true,否则返回 false。

尝试以下示例,显示基本操作方法的用法 -

例子

object Demo {
   def main(args: Array[String]) {
      val fruit = Set("apples", "oranges", "pears")
      val nums: Set[Int] = Set()
      println( "Head of fruit : " + fruit.head )
      println( "Tail of fruit : " + fruit.tail )
      println( "Check if fruit is empty : " + fruit.isEmpty )
      println( "Check if nums is empty : " + nums.isEmpty )
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

Head of fruit : apples
Tail of fruit : Set(oranges, pears)
Check if fruit is empty : false
Check if nums is empty : true

连接集合

您可以使用++运算符或Set.++()方法来连接两个或多个集合,但在添加集合时,它将删除重复元素。

以下是连接两个集合的示例。

例子

object Demo {
   def main(args: Array[String]) {
      val fruit1 = Set("apples", "oranges", "pears")
      val fruit2 = Set("mangoes", "banana")
      // use two or more sets with ++ as operator
      var fruit = fruit1 ++ fruit2
      println( "fruit1 ++ fruit2 : " + fruit )
      // use two sets with ++ as method
      fruit = fruit1.++(fruit2)
      println( "fruit1.++(fruit2) : " + fruit )
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

fruit1 ++ fruit2 : Set(banana, apples, mangoes, pears, oranges)
fruit1.++(fruit2) : Set(banana, apples, mangoes, pears, oranges)

查找集合中的最大、最小元素

您可以使用Set.min方法找出最小值,使用Set.max方法找出集合中可用元素的最大值。以下是展示该程序的示例。

例子

object Demo {
   def main(args: Array[String]) {
      val num = Set(5,6,9,20,30,45)
      // find min and max of the elements
      println( "Min element in Set(5,6,9,20,30,45) : " + num.min )
      println( "Max element in Set(5,6,9,20,30,45) : " + num.max )
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

Min element in Set(5,6,9,20,30,45) : 5
Max element in Set(5,6,9,20,30,45) : 45

寻找共同价值观插图

您可以使用Set.&方法或Set.intersect方法来找出两个集合之间的公共值。尝试以下示例来展示用法。

例子

object Demo {
   def main(args: Array[String]) {
      val num1 = Set(5,6,9,20,30,45)
      val num2 = Set(50,60,9,20,35,55)
      // find common elements between two sets
      println( "num1.&(num2) : " + num1.&(num2) )
      println( "num1.intersect(num2) : " + num1.intersect(num2) )
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

num1.&(num2) : Set(20, 9)
num1.intersect(num2) : Set(20, 9)

Scala 集合 - BitSet

Bitset 是可变和不可变位集的公共基类。位集是非负整数的集合,并表示为打包到 64 位字中的可变大小的位数组。位集的内存占用量由其中存储的最大数字表示。

声明 BitSet 变量

以下是声明 BitSet 变量的语法。

句法

var z : BitSet = BitSet(0,1,2)

这里,z 被声明为具有三个成员的非负整数位集。可以使用如下命令添加值 -

命令

var myList1: BitSet = myList + 3;

处理位集

下面是一个示例程序,展示了如何创建、初始化和处理 BitSet -

例子

import scala.collection.immutable.BitSet

object Demo {
   def main(args: Array[String]) = {
      var mySet: BitSet = BitSet(0, 1, 2);
      // Add an element
      var mySet1: BitSet = mySet + 3;
      // Remove an element
      var mySet2: BitSet = mySet - 2;
      var mySet3: BitSet = BitSet(4, 5);
      // Adding sets
      var mySet4: BitSet = mySet1 ++ mySet3;
      println(mySet);
      println(mySet1);
      println(mySet2);
      println(mySet4);	  
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

BitSet(0, 1, 2)
BitSet(0, 1, 2, 3)
BitSet(0, 1)
BitSet(0, 1, 2, 3, 4, 5)

Scala 集合 - HashSet

Scala Set 是同一类型的成对不同元素的集合。换句话说,Set 是不包含重复元素的集合。HashSet 实现不可变集并使用哈希表。不保留元素插入顺序。

声明 HashSet 变量

以下是声明 HashSet 变量的语法。

句法

var z : HashSet[String] = HashSet("Zara","Nuha","Ayan")

这里,z 被声明为具有三个成员的字符串哈希集。可以使用如下命令添加值 -

命令

var myList1: HashSet[String] = myList + "Naira";

处理哈希集

下面是一个示例程序,展示了如何创建、初始化和处理 HashSet -

例子

import scala.collection.immutable.HashSet
object Demo {
   def main(args: Array[String]) = {
      var mySet: HashSet[String] = HashSet("Zara","Nuha","Ayan");
      // Add an element
      var mySet1: HashSet[String] = mySet + "Naira";
      // Remove an element
      var mySet2: HashSet[String] = mySet - "Nuha";
      // Create empty set
      var mySet3: HashSet[String] = HashSet.empty[String];
      println(mySet);
      println(mySet1);
      println(mySet2);
      println(mySet3);	  
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

HashSet(Zara, Nuha, Ayan)
HashSet(Zara, Nuha, Ayan, Naira)
HashSet(Zara, Ayan)
HashSet()

Scala 集合 - TreeSet

Scala Set 是同一类型的成对不同元素的集合。换句话说,Set 是不包含重复元素的集合。TreeSet 实现不可变集并保持元素按排序顺序。

声明 TreeSet 变量

以下是声明 TreeSet 变量的语法。

句法

var z : TreeSet[String] = TreeSet("Zara","Nuha","Ayan")

这里,z 被声明为具有三个成员的字符串树集。可以使用如下命令添加值 -

命令

var myList1: TreeSet[String] = myList + "Naira";

处理树集

下面是一个示例程序,展示了如何创建、初始化和处理 TreeSet -

例子

import scala.collection.immutable.TreeSet

object Demo {
   def main(args: Array[String]) = {
      var mySet: TreeSet[String] = TreeSet("Zara","Nuha","Ayan");
      // Add an element
      var mySet1: TreeSet[String] = mySet + "Naira";
      // Remove an element
      var mySet2: TreeSet[String] = mySet - "Nuha";
      // Create empty set
      var mySet3: TreeSet[String] = TreeSet.empty[String];
      println(mySet);
      println(mySet1);
      println(mySet2);
      println(mySet3);	  
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

TreeSet(Ayan, Nuha, Zara)
TreeSet(Ayan, Naira, Nuha, Zara)
TreeSet(Ayan, Zara)
TreeSet()

Scala 集合 - 地图

Scala 映射是键/值对的集合。任何值都可以根据其键来检索。键在 Map 中是唯一的,但值不必是唯一的。映射也称为哈希表。Map 有两种,不可变的可变的。可变对象和不可变对象之间的区别在于,当对象不可变时,对象本身不能更改。

默认情况下,Scala 使用不可变的 Map。如果要使用可变 Map,则必须显式导入scala.collection.mutable.Map类。如果您想同时使用可变和不可变映射,那么您可以继续将不可变映射称为Map,但可以将可变集称为mutable.Map

以下是声明不可变映射的示例语句 -

// Empty hash table whose keys are strings and values are integers:
var A:Map[Char,Int] = Map()

// A map with keys and values.
val colors = Map("red" -> "#FF0000", "azure" -> "#F0FFFF")

在定义空映射时,类型注释是必要的,因为系统需要为变量分配具体类型。如果我们想向Map添加一个键值对,我们可以使用运算符+,如下所示。

A + = ('I' -> 1)
A + = ('J' -> 5)
A + = ('K' -> 10)
A + = ('L' -> 100)

MAP 基本操作

所有对地图的操作都可以用以下三种方法来表达。

先生编号 方法与说明
1

此方法返回一个包含映射中每个键的迭代。

2

价值观

此方法返回一个包含映射中每个值的迭代。

3

是空的

如果地图为空,则此方法返回 true,否则返回 false。

尝试以下示例程序,显示 Map 方法的用法。

例子

object Demo {
   def main(args: Array[String]) {
      val colors = Map(
         "red" -> "#FF0000", "azure" -> "#F0FFFF", "peru" -> "#CD853F"
      )
      val nums: Map[Int, Int] = Map()
      println( "Keys in colors : " + colors.keys )
      println( "Values in colors : " + colors.values )
      println( "Check if colors is empty : " + colors.isEmpty )
      println( "Check if nums is empty : " + nums.isEmpty )
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

Keys in colors : Set(red, azure, peru)
Values in colors : MapLike(#FF0000, #F0FFFF, #CD853F)
Check if colors is empty : false
Check if nums is empty : true

连接地图

您可以使用++运算符或Map.++()方法来连接两个或多个 Map,但在添加 Map 时,它将删除重复的键。

尝试以下示例程序来连接两个映射。

例子

object Demo {
   def main(args: Array[String]) {
      val colors1 = Map(
         "red" -> "#FF0000", "azure" -> "#F0FFFF", "peru" -> "#CD853F"
      )
      val colors2 = Map(
         "blue" -> "#0033FF", "yellow" -> "#FFFF00", "red" -> "#FF0000"
      )
      // use two or more Maps with ++ as operator
      var colors = colors1 ++ colors2
      println( "colors1 ++ colors2 : " + colors )
      // use two maps with ++ as method
      colors = colors1.++(colors2)
      println( "colors1.++(colors2)) : " + colors )
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

colors1 ++ colors2 : Map(blue -> #0033FF, azure -> #F0FFFF, 
   peru -> #CD853F, yellow -> #FFFF00, red -> #FF0000)

colors1.++(colors2)) : Map(blue -> #0033FF, azure -> #F0FFFF, 
   peru -> #CD853F, yellow -> #FFFF00, red -> #FF0000)

从地图打印键和值

您可以使用“foreach”循环遍历 Map 的键和值。在这里,我们使用与迭代器关联的方法foreach来遍历键。以下是示例程序。

例子

object Demo {
   def main(args: Array[String]) {
      val colors = Map("red" -> "#FF0000", "azure" -> "#F0FFFF","peru" -> "#CD853F")

      colors.keys.foreach{
         i =>  
         print( "Key = " + i )
         println(" Value = " + colors(i) )
      }
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

Key = red Value = #FF0000
Key = azure Value = #F0FFFF
Key = peru Value = #CD853F

检查地图中的密钥

您可以使用Map.contains方法来测试映射中是否存在给定的键。尝试使用以下示例程序进行密钥检查。

例子

object Demo {
   def main(args: Array[String]) {
      val colors = Map(
         "red" -> "#FF0000", "azure" -> "#F0FFFF", "peru" -> "#CD853F"
      )
      if( colors.contains( "red" )) {
         println("Red key exists with value :"  + colors("red"))
      } else {
         println("Red key does not exist")
      }
      if( colors.contains( "maroon" )) {
         println("Maroon key exists with value :"  + colors("maroon"))
      } else {
         println("Maroon key does not exist")
      }
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

Red key exists with value :#FF0000
Maroon key does not exist

Scala 集合 - HashMap

Scala 映射是键/值对的集合。任何值都可以根据其键来检索。键在 Map 中是唯一的,但值不必是唯一的。HashMap 实现了不可变映射,并使用哈希表来实现同样的映射。

声明 HashMap 变量

以下是声明 HashMap 变量的语法。

句法

val colors = HashMap("red" -> "#FF0000", "azure" -> "#F0FFFF", "peru" -> "#CD853F")

这里,颜色被声明为 Strings、Int 的哈希映射,它具有三个键值对。可以使用如下命令添加值 -

命令

var myMap1: HashMap[Char, Int] = colors + ("black" -> "#000000");

处理HashMap

下面是一个示例程序,展示了如何创建、初始化和处理 HashMap -

例子

import scala.collection.immutable.HashMap
object Demo {
   def main(args: Array[String]) = {
      var myMap: HashMap[String,String] = HashMap(
         "red" -> "#FF0000", "azure" -> "#F0FFFF", "peru" -> "#CD853F"
      );
      // Add an element
      var myMap1: HashMap[String,String] = myMap + ("white" -> "#FFFFFF");
      // Print key values
      myMap.keys.foreach{ 
         i =>  
         print( "Key = " + i )
         println(" Value = " + myMap(i) )
      }
      if( myMap.contains( "red" )) {
         println("Red key exists with value :"  + myMap("red"))
      } else {
         println("Red key does not exist")
      }
      if( myMap.contains( "maroon" )) {
         println("Maroon key exists with value :"  + myMap("maroon"))
      } else {
         println("Maroon key does not exist")
      }
      //removing element
      var myMap2: HashMap[String,String] = myMap - ("white");
      // Create empty map
      var myMap3: HashMap[String,String] = HashMap.empty[String, String];
      println(myMap1);
      println(myMap2);
      println(myMap3);		  
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

Key = azure Value = #F0FFFF
Key = peru Value = #CD853F
Key = red Value = #FF0000
Red key exists with value :#FF0000
Maroon key does not exist
HashMap(azure -> #F0FFFF, peru -> #CD853F, white -> #FFFFFF, red -> #FF0000)
HashMap(azure -> #F0FFFF, peru -> #CD853F, red -> #FF0000)
HashMap()

Scala 集合 - ListMap

Scala 映射是键/值对的集合。任何值都可以根据其键来检索。键在 Map 中是唯一的,但值不必是唯一的。ListMap 实现了不可变映射并使用 list 来实现相同的功能。它与少量元素一起使用。

声明 ListMap 变量

以下是声明 ListMap 变量的语法。

句法

val colors = ListMap("red" -> "#FF0000", "azure" -> "#F0FFFF", "peru" -> "#CD853F")

这里,颜色被声明为 Strings、Int 的哈希映射,它具有三个键值对。可以使用如下命令添加值 -

命令

var myMap1: ListMap[Char, Int] = colors + ("black" -> "#000000");

处理ListMap

下面是一个示例程序,展示了如何创建、初始化和处理 ListMap -

例子

import scala.collection.immutable.ListMap

object Demo {
   def main(args: Array[String]) = {
      var myMap: ListMap[String,String] = ListMap(
         "red" -> "#FF0000", "azure" -> "#F0FFFF", "peru" -> "#CD853F"
      );
      // Add an element
      var myMap1: ListMap[String,String] = myMap + ("white" -> "#FFFFFF");
      // Print key values
      myMap.keys.foreach{ 
         i =>  
         print( "Key = " + i )
         println(" Value = " + myMap(i) ) 
      }
      if( myMap.contains( "red" )) {
         println("Red key exists with value :"  + myMap("red"))
      } else {
         println("Red key does not exist")
      }
      if( myMap.contains( "maroon" )) {
         println("Maroon key exists with value :"  + myMap("maroon"))
      } else {
         println("Maroon key does not exist")
      }
      //removing element
      var myMap2: ListMap[String,String] = myMap - ("white");
      // Create empty map
      var myMap3: ListMap[String,String] = ListMap.empty[String, String];
      println(myMap1);
      println(myMap2);	
      println(myMap3);		  
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

Key = red Value = #FF0000
Key = azure Value = #F0FFFF
Key = peru Value = #CD853F
Red key exists with value :#FF0000
Maroon key does not exist
ListMap(red -> #FF0000, azure -> #F0FFFF, peru -> #CD853F, white -> #FFFFFF)
ListMap(red -> #FF0000, azure -> #F0FFFF, peru -> #CD853F)
ListMap()

Scala 集合 - 迭代器

迭代器不是集合,而是一种逐个访问集合元素的方法。迭代器的两个基本操作是nexthasNext对it.next()的调用将返回迭代器的下一个元素并推进迭代器的状态。您可以使用 Iterator 的it.hasNext方法了解是否有更多元素要返回。

“单步执行”迭代器返回的所有元素的最直接方法是使用 while 循环。让我们按照以下示例程序进行操作。

例子

object Demo {
   def main(args: Array[String]) {
      val it = Iterator("a", "number", "of", "words")
      while (it.hasNext){
         println(it.next())
      }
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

a
number
of
words

查找最小和最大值元素

您可以使用it.minit.max方法从迭代器中找出最小值和最大值元素。这里,我们使用itaitb来执行两个不同的操作,因为迭代器只能遍历一次。以下是示例程序。

例子

object Demo {
   def main(args: Array[String]) {
      val ita = Iterator(20,40,2,50,69, 90)
      val itb = Iterator(20,40,2,50,69, 90)
      println("Maximum valued element " + ita.max )
      println("Minimum valued element " + itb.min )
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

Maximum valued element 90
Minimum valued element 2

求迭代器的长度

您可以使用it.sizeit.length方法来查找迭代器中可用元素的数量。这里,我们使用 ita 和 itb 来执行两个不同的操作,因为迭代器只能遍历一次。以下是示例程序。

例子

object Demo {
   def main(args: Array[String]) {
      val ita = Iterator(20,40,2,50,69, 90)
      val itb = Iterator(20,40,2,50,69, 90)
      println("Value of ita.size : " + ita.size )
      println("Value of itb.length : " + itb.length )
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

Value of ita.size : 6
Value of itb.length : 6

Scala 集合 - 选项

Scala Option[ T ] 是给定类型的零个或一个元素的容器。Option[T] 可以是Some[T]None对象,它表示缺失值。例如,如果找到与给定键对应的值,则 Scala 的 Map 的 get 方法将生成 Some(value);如果给定键未在 Map 中定义,则生成None 。

选项类型在 Scala 程序中经常使用,您可以将其与Java 中表示没有值的空值进行比较。例如,java.util.HashMap 的 get 方法返回存储在 HashMap 中的值,如果未找到值,则返回 null。

假设我们有一个根据主键从数据库检索记录的方法。

def findPerson(key: Int): Option[Person]

如果找到记录,该方法将返回 Some[Person];如果未找到记录,则返回 None。让我们按照以下程序进行操作。

例子

object Demo {
   def main(args: Array[String]) {
      val capitals = Map("France" -> "Paris", "Japan" -> "Tokyo")
      println("capitals.get( \"France\" ) : " +  capitals.get( "France" ))
      println("capitals.get( \"India\" ) : " +  capitals.get( "India" ))
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

capitals.get( "France" ) : Some(Paris)
capitals.get( "India" ) : None

分离可选值的最常见方法是通过模式匹配。例如尝试以下程序。

例子

object Demo {
   def main(args: Array[String]) {
      val capitals = Map("France" -> "Paris", "Japan" -> "Tokyo")
      println("show(capitals.get( \"Japan\")) : " + show(capitals.get( "Japan")) )
      println("show(capitals.get( \"India\")) : " + show(capitals.get( "India")) )
   }
   def show(x: Option[String]) = x match {
      case Some(s) => s
      case None => "?"
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

show(capitals.get( "Japan")) : Tokyo
show(capitals.get( "India")) : ?

使用 getOrElse() 方法

以下示例程序展示了如何使用 getOrElse() 方法在不存在值时访问值或默认值。

例子

object Demo {
   def main(args: Array[String]) {
      val a:Option[Int] = Some(5)
      val b:Option[Int] = None 
      println("a.getOrElse(0): " + a.getOrElse(0) )
      println("b.getOrElse(10): " + b.getOrElse(10) )
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

a.getOrElse(0): 5
b.getOrElse(10): 10

使用 isEmpty() 方法

下面的示例程序展示了如何使用 isEmpty() 方法来检查选项是否为 None 。

例子

object Demo {
   def main(args: Array[String]) {
      val a:Option[Int] = Some(5)
      val b:Option[Int] = None 
      println("a.isEmpty: " + a.isEmpty )
      println("b.isEmpty: " + b.isEmpty )
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

例子

a.isEmpty: false
b.isEmpty: true

Scala 集合 - 队列

队列是先进先出、先进先出的数据结构,允许以先进先出的方式插入和检索元素。

声明队列变量

以下是声明队列变量的语法。

句法

val queue = Queue(1, 2, 3, 4, 5)

这里,队列被声明为数字队列。可以使用如下命令在前面添加值 -

命令

queue.enqueue(6)

可以使用如下命令在前面检索值 -

命令

queue.dequeue()

处理队列

下面是一个示例程序,展示了如何创建、初始化和处理队列 -

例子

import scala.collection.mutable.Queue
object Demo {
   def main(args: Array[String]) = {
      var queue = Queue(1, 2, 3, 4, 5);
      // Print queue elements
      queue.foreach{(element:Int) => print(element + " ")}
      println();
      // Print first element
      println("First Element: " + queue.front)
      // Add an element
      queue.enqueue(6);
      // Print queue elements
      queue.foreach{(element:Int) => print(element+ " ")}
      println();
      // Remove an element
      var dq = queue.dequeue;
      // Print dequeued element
      println("Dequeued Element: " + dq)
      // Print queue elements
      queue.foreach{(element:Int) => print(element+ " ")}
   }
}

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

命令

\>scalac Demo.scala
\>scala Demo

输出

1 2 3 4 5
First Element: 1
1 2 3 4 5 6
Dequeued Element: 1
2 3 4 5 6

Scala 集合 - 元组

Scala 元组将固定数量的项组合在一起,以便它们可以作为一个整体传递。与数组或列表不同,元组可以保存不同类型的对象,但它们也是不可变的。

以下是包含整数、字符串和控制台的元组示例。

val t = (1, "hello", Console)

这是以下语法糖(快捷方式) -

val t = new Tuple3(1, "hello", Console)

元组的实际类型取决于它包含的元素的数量和元素以及这些元素的类型。因此,(99, "Luftballons") 的类型是 Tuple2[Int, String]。('u', 'r', "the", 1, 4, "me") 的类型为 Tuple6[Char, Char, String, Int, Int, String]

元组的类型有 Tuple1、Tuple2、Tuple3 等。目前Scala的上限是22,如果你需要更多,那么你可以使用集合,而不是元组。对于每个 TupleN 类型(其中 1 <= N <= 22),Scala 定义了许多元素访问方法。鉴于以下定义 -

val t = (4,3,2,1)

要访问元组 t 的元素,可以使用方法 t._1 访问第一个元素,使用 t._2 访问第二个元素,依此类推。例如,以下表达式计算 t 的所有元素的总和。

val sum = t._1 + t._2 + t._3 + t._4

您可以使用 Tuple 编写一个方法,该方法采用 List[Double] 并返回计数、总和以及返回的平方和