集合

Table of Contents

1 数组(array)

1.1 数组操作

1.1.1 构造数组

val a = Array(1, 2, 3)
val a = new Array[Int](3) // 指定元素类型

还可以调用 Array 类的 apply 方法:

Array.apply(1, 2, 3)

1.1.2 访问数组

索引数组类似方法调用,索引从下标 0 开始。

var words = Array("a", "b", "c")
println(words(0)) // => a

1.1.3 更新数组元素

方法一,使用 update 方法:

a.update(0, 100)

方法二,直接按索引更新:

a(0) = 100

1.1.4 打印数组元素

println(Array(1, 2, 3)) // [[email protected],默认无法打印全部元素
println(Array(1, 2, 3).deep) // Array(1, 2, 3)
println(Array(1,2,3).mkString)

1.1.5 遍历数组

数组定义如下:

val words = Array("a", "b", "c")

方法1:

for (word <- words) println(word)

方法2:

words.foreach(println(_))

遍历时加入下标:

for ((i, word) <- words.zipWithIndex) println(i, word)

1.2 可变数组

刚才演示的都是不可变数组。可变数组的用法如下:

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

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

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

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

scala> ab
res2: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2)

1.3 把 Array 类型转换成可变数组

scala> val aBuffer = a.toBuffer
aBuffer: scala.collection.mutable.Buffer[Int] = ArrayBuffer()

scala> aBuffer += 1
res4: aBuffer.type = ArrayBuffer(1)

scala> aBuffer
res5: scala.collection.mutable.Buffer[Int] = ArrayBuffer(1)

1.4 Array 应用1:接受脚本参数

运行一个 Scala 脚本时,如果传递了参数,参数信息保存在 args 数组里,可以直接引用:

// hello.scala
println(args(0))

2 列表(list)

2.1 构造列表

val = aList = List(1, 2, 3) // 其实等价于 List.apply(1, 2, 3)
val aList: List[Int] = List(1, 2, 3)
val aList: List[String] = List("1", "2", "3")
// 嵌套列表
val aList: List[List[Int]] = List(List(1, 2, 3))
// 空列表
val aList: List[Nothing] = Nil 或 val aList: List[Nothing] = List()
// 创建范围
val aList = List.range(1, 5) // List(1, 2, 3, 4)
// 重复填充元素,注:老版本 Scala 用的 make 方法:List.make(5, 'a')
val aList = List.fill(5)('a') // List(a, a, a, a, a)
List.fill(3, 2)('a') // List(List(a, a), List(a, a), List(a, a))

还可用“::” cons 操作来构造列表(类似 Lisp):

1 :: 2 :: 3 :: Nil

Nil 表示空列表,类似 Lisp 里的 nil。

用“:::”构造的列表就是平坦的:

scala> List(1, 2) ::: List(3, 4)
res11: List[Int] = List(1, 2, 3, 4)

2.2 列表操作

2.2.1 列表fold

其实就是Reduce操作,使用(start :/ List) (op)形式:

def sum(xs: List[Int]): Int = (0 /: xs) (_ + _)
sum(List(1, 2, 3)) // 6

如果使用“\:”表示从左边开始fold:

def sum(xs: List[Int]): Int = (xs :\ 0) (_ + _)
sum(List(1, 2, 3)) // 6

上面代码表示(1 + ( 2 + (3 + 0)))。

2.2.2 tabulate

可以让每个元素都应用到一个函数:

scala> List.tabulate(5)(_ * 10)
res23: List[Int] = List(0, 10, 20, 30, 40)

2.2.3 mkString

类似Python中的字符串join操作:

scala> List(1, 2, 3).mkString(",")
res0: String = 1,2,3

2.3 可变List

import scala.collection.mutable.ListBuffer

操作示例:

scala> val aList = ListBuffer[Int]()
aList: scala.collection.mutable.ListBuffer[Int] = ListBuffer()

scala> aList += 1
res1: aList.type = ListBuffer(1)

scala> aList += 2
res2: aList.type = ListBuffer(1, 2)

scala> aList
res3: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2)

scala> aNewList.to[List
List   ListBuffer

scala> aNewList.to[ListBuffer] // List类型转换成ListBuffer类型,互转方法相同
res4: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3)

3 元组(tuple)

Tuple 类似 List,不同的是 tuple 能包含不同类型元素,并且元素是固定不可变的。

3.1 构造 Tuple

(1, 2, 3, "4")

3.2 访问 Tuple

Tuple 下标从 1 开始,而不是 0:

scala> (1, 2, 3, "4")._1
res34: Int = 1

3.3 二元元组

("a" -> 1)

3.4 定义返回类型为元组的函数

scala> def test() = ("a", "1")
test: ()(String, String)

或者指定返回值类型:

scala> def test(): (String, String) = ("a", "1")
test: ()(String, String)

4 集合(set)

集合包含不重复元素,也无顺序。

4.1 构造集合

Set(1, 2, 3, 3)

判断相等:

Set(1, 2, 3) == Set(1, 3, 2)

4.2 增加和删除元素

使用“+”方法增加元素:

var aSet = Set(1, 2, 3, 3)
aSet += 4  // 由于 + 不会产生副作用,所以需要重新赋值

删除元素:

var aSet = Set(1, 2, 3)
aSet -= 3 // 如果不需要产生副作用,直接 aSet - 3 即可

4.3 交集

Set(1, 2, 3) & Set(1, 3, 5)

4.4 并集

Set(1, 2, 3) ++ Set(1, 3, 5)

4.5 补集

Set(1, 2, 3) -- Set(1, 3, 5)

5 映射(map)

特点:

  • 映射的值甚至可以是函数
  • 值不可变
  • 键类型要一致

5.1 创建 Map

Map("a" -> 1, "b" -> 2)

实际 Map 的每个 key-value 对,都二元元组组成。

5.2 访问

scala> Map("a" -> 1, "b" -> 2)("a")
res43: Int = 1

5.3 增加和删除元素

增加元素:

x + ("c" -> 3) // 不会修改原对象,而是返回新的

删除元素:

x - "b"  // 不会修改原对象

5.4 可变 Map(HashMap)

scala> import scala.collection.mutable.HashMap
import scala.collection.mutable.HashMap

scala> val m = HashMap("a" -> 1)
m: scala.collection.mutable.HashMap[String,Int] = Map(a -> 1)

scala> m.update("b", 2)

scala> m
res2: scala.collection.mutable.HashMap[String,Int] = Map(b -> 2, a -> 1)

6 集合类型之间的转换

println(Array("a", "b", "c").toList) // => List(a, b, c)
println(List("a", "b", "c").toArray) // => [Ljava.lang.String;@6d311334
println(Array("a", "a", "a").toSet) // => Set(a)
println(List(("a", 1), ("b", 2)).toMap) // => Map(a -> 1, b -> 2)

6.1 列表转 Map

scala> val aList = List("a", "b", "c")
aList: List[String] = List(a, b, c)

scala> aList.map(_ -> true).toMap
res1: scala.collection.immutable.Map[String,Boolean] = Map(a -> true, b -> true, c -> true)

7 组合子

map:

List(1, 2, 3, 4).map((i: Int) => i * 2)

foreach:

类似 map,但没有返回值,一般用在有副作用的

filter:

如,移除返回为 false 的结果:

x.filter((i: Int) => i % 2 == 0)

zip:

两个列表聚合成一个聚偶列表

partition:

按谓词函数分割列表

find:

返回第一个被谓词函数匹配到的元素

flatten:

扁平化两个列表