快速入门Scala(六):数组与集合

分类目录:《快速入门Scala》总目录

Scala中提供的数组(Array)是用来存储固定大小的同类型元素,数组对于每一门编辑应语言来说都是重要的数据结构之一。除此之外,Scala还提供了一套很好的集合( Collection)实现,提供了一些集合类型的抽象。

数组

数组声明的语法格式:

val arr:Array[Int] = new Array[Int](Length)   //第一种方式
val arr: = new Array[Int](Length)             //第二种方式
val arr: = Array[Int](1, 2, 3)                //第三种方式

声明数组的第一种方式与第二种方式类似,返回都为长度为 L e n g t h Length Length,元素为 0 0 0(当指定元素为Int类型时)或null(当指定元素为String类型时)。其中,第二种方式声明数组是第一种方式的简写:

scala> val arr = new Array[Int](5)
arr: Array[Int] = Array(0, 0, 0, 0, 0)

scala> val arr = new Array(5)
arr: Array[Nothing] = Array(null, null, null, null, null)

需要注意的是,虽然我们使用val声明变量,但是val仅仅限制了变量的引用不能改变,对于声明的Array中的元素,仍然可以进行修改:

scala> val arr = new Array[Int](5)
arr: Array[Int] = Array(0, 0, 0, 0, 0)

scala> arr(0) = 1

scala> arr
res0: Array[Int] = Array(1, 0, 0, 0, 0)

声明数组的第三种方式在声明时就直接指定了其内部元素:

scala> val arr = Array(1, 2, 3, 4, 5)
arr: Array[Int] = Array(1, 2, 3, 4, 5)

多维数组

多维数组一个数组中的值可以是另一个数组,另一个数组的值也可以是一个数组。矩阵与表格是我们常见的二维数组:

scala> var myMatrix = Array.ofDim[Int](2,2)
myMatrix: Array[Array[Int]] = Array(Array(0, 0), Array(0, 0))

数组缓冲

上述使用Array声明的数组长度是固定的,如果想声明长度不是固定的数组就需要使用数组缓冲。使用数组缓冲需要提前导入ArrayBuffer包:

scala> import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.ArrayBuffer

scala> val arr = ArrayBuffer[Int](1, 2, 3)
arr: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3)

除此之外,也可以通过new ArrayBuffer新建一个空的数组缓冲,再通过+=append方法追加元素或元组或通过++=追加数组:

scala> val arr = new ArrayBuffer[Int]()
arr: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()

scala> arr += 1
res0: arr.type = ArrayBuffer(1)

scala> arr += (2, 3)
res1: arr.type = ArrayBuffer(1, 2, 3)

scala> arr ++= Array(4, 5, 6)
res2: arr.type = ArrayBuffer(1, 2, 3, 4, 5, 6)

scala> arr ++= ArrayBuffer(7, 8, 9)
res3: arr.type = ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9)

scala> arr.append(10, 11, 12)
scala> arr
res4: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

集合

Scala 集合分为可变的和不可变的集合。

可变集合可以在适当的地方被更新或扩展。这意味着你可以修改,添加,移除一个集合的元素。

而不可变集合类,相比之下,永远不会改变。不过,你仍然可以模拟添加,移除或更新操作。但是这些操作将在每一种情况下都返回一个新的集合,同时使原来的集合不发生改变。

列表(List)

Scala列表类似于数组,它们所有元素的类型都相同,但是列表是不可变的,值一旦被定义了就不能改变。其次,列表具有递归的结构(也就是链接表结构)而数组不是。

scala> val lst = List(1, 2, 3, 4, 5)
lst: List[Int] = List(1, 2, 3, 4, 5)

也可以使用List.fill()方法来创建一个指定重复数量的元素列表:

scala> val lst = List.fill(5)(0)
lst: List[Int] = List(0, 0, 0, 0, 0)

scala> val lst = List.fill(2)(1, 2, 3)
lst: List[(Int, Int, Int)] = List((1,2,3), (1,2,3))

也可以使用List.tabulate()方法通过给定的函数来创建列表。方法的第一个参数为元素的数量,可以是二维的,第二个参数为指定的函数,我们通过指定的函数计算结果并返回值插入到列表中,起始值为 0:

scala> val lst = List.tabulate(3)(x => x * x)
lst: List[Int] = List(0, 1, 4)
列表的增、删、改

使用+::::+在列表的前和后添加元素:

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

scala> 0 +: lst
res0: List[Int] = List(0, 1, 2, 3)

scala> lst :+ 4
res1: List[Int] = List(1, 2, 3, 4)

scala> 0 :: lst
res2: List[Int] = List(0, 1, 2, 3)

使用:::连接两个列表:

scala> val lst_1 = List(0, 1, 2)
lst_1: List[Int] = List(0, 1, 2)

scala> val lst_2 = List(3, 4, 5)
lst_2: List[Int] = List(3, 4, 5)

scala> lst_1 ::: lst_2
res26: List[Int] = List(0, 1, 2, 3, 4, 5)

上述的方法都不会直接对原List进行操作,如果要保存结果需要对lst重新赋值。

列表常用方法
  • .head:返回列表第一个元素
  • .tail:返回一个列表,包含除了第一元素之外的其他元素
  • .isEmpty:在列表为空时返回true
  • .reverse:将列表的顺序反转
  • .contains(elem: Any):检测列表中是否包含指定的元素
  • .copyToArray(xs: Array[A], start: Int, len: Int):将列表的元素复制到数组中
  • .distinct:去除列表的重复元素,并返回新列表
  • .drop(n: Int):丢弃前n个元素,并返回新列表
  • .dropRight(n: Int):丢弃最后n个元素,并返回新列表
  • .dropWhile(p: (A) => Boolean):从左向右丢弃元素,直到条件p不成立
  • .endsWith[B](that: Seq[B]):检测列表是否以指定序列结尾
  • .equals(that: Any):判断是否相等
  • .exists(p: (A) => Boolean):判断列表中指定条件的元素是否存在
  • .filter(p: (A) => Boolean):输出符号指定条件的所有元素
  • .foreach(f: (A) => Unit):将函数应用到列表的所有元素
  • .indexOf(elem: A, from: Int):从指定位置 from 开始查找元素第一次出现的位置
  • .init:返回所有元素,除了最后一个
  • .intersect(that: Seq[A]):计算多个集合的交集
  • .isEmpty:检测列表是否为空
  • .iterator:创建一个新的迭代器来迭代元素
  • .last: 返回最后一个元素
  • .lastIndexOf(elem: A, end: Int):在指定的位置 end 开始查找元素最后出现的位
  • .length:返回列表长度
  • .map[B](f: (A) => B):通过给定的方法将所有元素重新计算
  • .max:查找最大元素
  • .min:查找最小元素
  • .mkString:列表所有元素作为字符串显示
  • .reverse:列表反转
  • .sorted[B >: A]:列表排序
  • .startsWith[B](that: Seq[B], offset: Int):检测列表在指定位置是否包含指定序列
  • .sum:计算集合元素之和
  • .take(n: Int):提取列表的前n个元素
  • .takeRight(n: Int):提取列表的后n个元素
  • .toArray:列表转换为数组
  • .toBuffer[B >: A]:返回缓冲区,包含了列表的所有元素
  • .toMap[T, U]:列表转换为 Map
  • .toSeq:列表转换为 Seq
  • .toSet[B >: A]:列表转换为 Set
  • .toString():列表转换为字符串

集合(Set)

Scala Set(集合)是没有重复的对象集合,所有的元素都是唯一的。Scala 集合分为可变的和不可变的集合。默认情况下,Scala 使用的是不可变集合,如果你想使用可变集合,需要引用 scala.collection.mutable.Set 包:

scala> import scala.collection.mutable.Set
import scala.collection.mutable.Set

scala> val s = Set(1, 2, 3)
s: scala.collection.mutable.Set[Int] = Set(1, 2, 3)
集合的的增、删、改

集合增加元素与删除元素:

scala> import scala.collection.mutable.Set
import scala.collection.mutable.Set

scala> val s = Set(1, 2, 3)
s: scala.collection.mutable.Set[Int] = Set(1, 2, 3)

scala> s.add(4)
res0: Boolean = true

scala> s += 5
res1: s.type = Set(1, 5, 2, 3, 4)

scala> s.remove(5)
res2: Boolean = true

scala> s -= 4
res3: s.type = Set(1, 2, 3)

使用++运算符或Set.++()方法来求两个集合的并集,使用Set.&Set.intersect来求两个集合的交集,用Set.&~来求两个集合的差集:

scala> val s1 = Set(1, 2, 3, 4, 5)
s1: scala.collection.mutable.Set[Int] = Set(1, 5, 2, 3, 4)

scala> val s2 = Set(2, 4, 6, 8)
s2: scala.collection.mutable.Set[Int] = Set(2, 6, 4, 8)

scala> s1 ++ s2
res0: scala.collection.mutable.Set[Int] = Set(1, 5, 2, 6, 3, 4, 8)

scala> s1.intersect(s2)
res1: scala.collection.mutable.Set[Int] = Set(2, 4)

scala> s1.&~(s2)
res2: scala.collection.mutable.Set[Int] = Set(1, 5, 3)
集合常用方法
  • .head:返回集合第一个元素
  • .tail:返回一个集合,包含除了第一元素之外的其他元素
  • .isEmpty:在集合为空时返回true
  • .contains(elem: Any):检测列表中是否包含指定的元素
  • .drop(n: Int):丢弃前n个元素,并返回新集合
  • .dropRight(n: Int):丢弃最后n个元素,并返回新集合
  • .dropWhile(p: (A) => Boolean):从左向右丢弃元素,直到条件p不成立
  • .equals(that: Any):判断是否相等
  • .exists(p: (A) => Boolean):判断集合中指定条件的元素是否存在
  • .filter(p: (A) => Boolean):输出符号指定条件的所有元素
  • .find(p: (A) => Boolean):查找不可变集合中满足指定条件的第一个元素
  • .forall(p: (A) => Boolean):查找不可变集合中满足指定条件的所有元素
  • .foreach(f: (A) => Unit):将函数应用到列表的所有元素
  • .init:返回所有元素,除了最后一个
  • .intersect(that: Seq[A]):计算多个集合的交集
  • .isEmpty:检测集合是否为空
  • .iterator:创建一个新的迭代器来迭代元素
  • .last: 返回最后一个元素
  • .length:返回列表长度
  • .map[B](f: (A) => B):通过给定的方法将所有元素重新计算
  • .max:查找最大元素
  • .min:查找最小元素
  • .mkString:集合所有元素作为字符串显示
  • .product:返回不可变集合中数字元素的积
  • .size:返回不可变集合元素的数量
  • .splitAt(n: Int):把不可变集合拆分为两个容器,第一个由前n个元素组成,第二个由剩下的元素组成
  • .subsetOf(that: Set[A]):如果集合中含有子集返回 true,否则返回false
  • .sum:计算集合元素之和
  • .toArray:集合转换为数组
  • .toBuffer[B >: A]:返回缓冲区,包含了列表的所有元素
  • .toMap[T, U]:集合转换为 Map
  • .toSeq:集合转换为 Seq
  • .toList[B >: A]:集合转换为列表
  • .toString():集合转换为字符串

映射(Map)

映射(Map),也叫哈希表(Hash tables)是一种可迭代的键值对(key/value)结构,所有的值都可以通过键来获取,且键都是唯一的。Map有两种类型,可变与不可变,区别在于可变对象可以修改它,而不可变对象不可以。默认情况下 Scala 使用不可变 Map。如果你需要使用可变集合,你需要显式的引入 import scala.collection.mutable.Map 类。在 Scala 中 你可以同时使用可变与不可变 Map,不可变的直接使用 Map,可变的使用 mutable.Map:

scala> import scala.collection.mutable.Map
import scala.collection.mutable.Map

scala> val m : Map[Char, Int] = Map()
m: scala.collection.mutable.Map[Char,Int] = Map()

scala> m += ('A' -> 1)
res0: m.type = Map(A -> 1)

scala> m += ('B' -> 2)
res1: m.type = Map(A -> 1, B -> 2)

使用++运算符或Map.++()方法来连接两个Map,Map合并时会移除重复的key:

scala> val colors1 = Map("red" -> "#FF0000", "azure" -> "#F0FFFF", "peru" -> "#CD853F")
colors1: scala.collection.mutable.Map[String,String] = Map(azure -> #F0FFFF, red -> #FF0000, peru -> #CD853F)

scala> val colors2 = Map("blue" -> "#0033FF", "yellow" -> "#FFFF00", "red" -> "#FF0000")
colors2: scala.collection.mutable.Map[String,String] = Map(yellow -> #FFFF00, red -> #FF0000, blue -> #0033FF)

scala> colors1 ++ colors2
res0: scala.collection.mutable.Map[String,String] = Map(yellow -> #FFFF00, azure -> #F0FFFF, red -> #FF0000, peru -> #CD853F, blue -> #0033FF)
映射常用方法
  • .get(key: A):返回指定 key 的值
  • .iterator:创建新的迭代器,并输出 key/value 对
  • .addString(b: StringBuilder):将Map中的所有元素附加到StringBuilder,可加入分隔符
  • .addString(b: StringBuilder, sep: String):将Map中的所有元素附加到StringBuilder,可加入分隔符
  • .clear():清空 Map
  • .clone():从一个 Map 复制到另一个 Map
  • .contains(key: A):如果Map中存在指定key,返回true,否则返回false
  • .copyToArray(xs: Array[(A, B)]):复制集合到数组
  • .count(p: ((A, B)) => Boolean):计算满足指定条件的集合元素数量
  • .default(key: A):定义Map的默认值,在key不存在时返回
  • .drop(n: Int):返回丢弃前n个元素新集合
  • .dropRight(n: Int):返回丢弃最后n个元素新集合
  • .dropWhile(p: ((A, B)) => Boolean):从左向右丢弃元素,直到条件p不成立
  • .empty:返回相同类型的空Map
  • .equals(that: Any):如果两个Map相等(key/value 均相等),返回true,否则返回false
  • .exists(p: ((A, B)) => Boolean):判断集合中指定条件的元素是否存在
  • .filter(p: ((A, B))=> Boolean):返回满足指定条件的所有集合
  • .filterKeys(p: (A) => Boolean):返回符合指定条件的不可变 Map
  • .find(p: ((A, B)) => Boolean):查找集合中满足指定条件的第一个元素
  • .foreach(f: ((A, B)) => Unit):将函数应用到集合的所有元素
  • .init:返回所有元素,除了最后一个
  • .isEmpty:检测 Map 是否为空
  • .keys::返回所有的key
  • . last:返回最后一个元素
  • .max:查找最大元素
  • . min:查找最小元素
  • .mkString:集合所有元素作为字符串显示
  • .product:返回集合中数字元素的积。
  • .remove(key: A):移除指定 key
  • .retain(p: (A, B) => Boolean):如果符合满足条件的返回true
  • .size:返回 Map 元素的个数
  • .sum:返回集合中所有数字元素之和
  • .tail:返回一个集合中除了第一元素之外的其他元素
  • .take(n: Int):返回前 n 个元素
  • .takeRight(n: Int):返回后 n 个元素
  • .takeWhile(p: ((A, B)) => Boolean):返回满足指定条件的元素
  • .toArray:集合转数组
  • .toBuffer[B >: A]:返回缓冲区,包含了 Map 的所有元素
  • .toList:返回 List,包含了Map的所有元素
  • .toSeq:返回 Seq,包含了Map的所有元素
  • . toSet:返回 Set,包含了 Map 的所有元素
  • .toString():返回字符串对象

元组

与列表一样,元组也是不可变的,但与列表不同的是元组可以包含不同类型的元素。元组的值通过将单个的值包含在圆括号中构成。目前 Scala 支持的元组最大长度为 22。对于更大长度,可以使用集合,或者扩展元组。在元组中,使用 ._n 访问第 n n n个元素:

scala> val t = (1, 1.0, 1L, "Hello World!")
t: (Int, Double, Long, String) = (1,1.0,1,Hello World!)

scala> val t = new Tuple4(1, 1.0, 1L, "Hello World!")
t: (Int, Double, Long, String) = (1,1.0,1,Hello World!)

scala> t._1
res0: Int = 1

你可能感兴趣的:(快速入门Scala)