不可变集合
Nil
是Nothing
类型实例,Nothing
类型是所有其他Scala
类型的一个不可实例化的子类型。List
: 空的表等于Nil
,表尾部后一个是Nil
。- 头尾取不一样:
1
2
3
4
5
6
7
8scala> primes
val res3: List[Int] = List(2, 3, 5, 7, 11, 13)
scala> primes.head
val res5: Int = 2
scala> primes.tail
val res6: List[Int] = List(3, 5, 7, 11, 13)foreach
、map
、reduce
( 两个参数)::
右操作符是List
的放法:1
2
3
4
5
6
7
8
9
10
11
12scala> val first = Nil.::(1)
val first: List[Int] = List(1)
//生成List
scala> val first = 1:: Nil
val first: List[Int] = List(1)
//用::在List前面增加元素
scala> val second = 2 :: first
val second: List[Int] = List(2, 1)
scala> second.tail == first
val res39: Boolean = true其他操作符:
操作符记法
:List drop 2
- 点记法:
List.flatten
- 差别:没有参数时,必须采用点记法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71//空List前面加元素
scala> val first = 1:: Nil
val first: List[Int] = List(1)
//List合并List
scala> List(1, 2) ::: List(2, 3)
val res40: List[Int] = List(1, 2, 2, 3)
//List合并集合
scala> List(1, 2) ++ Set(3, 4, 3)
val res41: List[Int] = List(1, 2, 3, 4)
//List比较
scala> List(1, 2) == List(1, 2)
val res42: Boolean = true
//取唯一元素
scala> List(2, 3, 4, 5, 3).distinct
val res43: List[Int] = List(2, 3, 4, 5)
//丢带前k个元素
scala> List('a', 'b', 'c', 'd') drop 2
val res44: List[Char] = List(c, d)
//谓词函数塞选
scala> List(23, 8, 14, 21) filter (_ > 18)
val res45: List[Int] = List(23, 21)
//归并List
scala> List(List(1, 2), List(3, 4)).flatten
val res46: List[Int] = List(1, 2, 3, 4)
//按条件分割List
scala> List(1,2,3,4,5) partition ( _ < 3)
val res48: (List[Int], List[Int]) = (List(1, 2),List(3, 4, 5))
//切割[i,j)內的元素
scala> List(1, 2, 3) slice (1, 3)
val res49: List[Int] = List(2, 3)
//谓词函数排序
scala> List("apple", "to") sortBy (_.size)
val res51: List[String] = List(to, apple)
//字典顺序排序
scala> List("apple", "to").sorted
val res52: List[String] = List(apple, to)
// 在位置做切割
scala> List(2, 3, 5, 7) splitAt 2
val res53: (List[Int], List[Int]) = (List(2, 3),List(5, 7))
//取出前k个
scala> List(2, 3, 5, 7, 11, 13) take 3
val res54: List[Int] = List(2, 3, 5)
//zip
scala> List(1, 2) zip List ("a", "b")
val res55: List[(Int, String)] = List((1,a), (2,b))
// List尾部追加元素
scala> val appended = List(1, 2, 3, 4) :+ 5
val appended: List[Int] = List(1, 2, 3, 4, 5)
// 取右边k个值
scala> val suffix = appended takeRight 3
val suffix: List[Int] = List(3, 4, 5)
//丢弃右边k个值
scala> val middle = suffix dropRight 2
val middle: List[Int] = List(3)
- 映射函数:
1 | scala> List(0, 1, 0) collect {case 1 => "ok"} |
- 规约函数:
1 | scala> List(32, 29) contains 29 |
- 抽象规约函数:
1 | scala> def reduceOp[A, B](l: List[A], start: B) (f: (B, A) => B): B = { |
系统自带的该类函数:
- 顺序地迭代与无序迭代区别开:提高分布式下的效率;
- 左归约效率高于右归约
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33//给定一个起始值和一个归约函数归约列表
scala> List(4, 5, 6).fold(0)(_ + _)
val res77: Int = 15
scala> List(4, 5, 6).fold(1)(_ + _)
val res78: Int = 16
//从左到右归约
scala> List(4, 5, 6).foldLeft(0)(_ + _)
val res80: Int = 15
//无序归约
scala> List(4, 5, 6).reduce(_ + _)
val res85: Int = 15
//从左开始
scala> List(4, 5, 6).reduceLeft(_ + _)
val res89: Int = 15
//返回各个累加值
scala> List(4, 5, 6).scan(0)(_ + _)
val res90: List[Int] = List(0, 4, 9, 15)
//tag,j是自定义的变量名,false取过来初始化tag,j被List本身初始化
scala> val included = List(46, 19, 92).foldLeft(false) {
| (tag, j) => if(tag) tag else (j == 19)
| }
val included: Boolean = true
//不给初始化值的时候,用List的第一个值初始化
scala> List(24, 44, 33).reduceLeft(_ + _)
val res93: Int = 101
转换集合
1 | scala> List(24, 44, 33).reduceLeft(_ + _) |
JAVA集合兼容性
1 | import scala.jdk.CollectionConverters._ |
集合模式匹配
1 | //匹配头节点 |
1 | scala> val msg = List(500, 404) match { |
元组匹配:
1
2
3
4
5
6
7
8
9
10
11scala> val code = ('h', 204, true) match {
| case (_, _, false) => 501
| case ('c',_, true) => 302
| case ('h', x, true) => x
| case (c, x, true) => {
| println(s"Did not expect code $c")
| x
| }
| }
val code: Int = 204
可变集合
collection.immutable
会自动增加到scala的命名空间,所以用可变集合要写全了。
1 | scala> val nums = collection.mutable.Buffer(1) |
Builder
:Buffer
的简化形式,只支持追加操作,生成集合类型。适合用于迭代的构建一个可变集合并转换为不可变集合的情况。
1 | //创建Buffer |
Array
:Java数组类型的包装器,除非JVM中使用。1
2scala> val colors = Array("red", "green", "blue")
val colors: Array[String] = Array(red, green, blue)
Seq
Seq
是所有序列的根类型,下面是IndexedSeq
索引序列(Vector
、Range
),和LinearSeq
线型链表序列(List
,stream
,Queue/Stack
)
1 | scala> val hi = "hello, " ++ "worldly" take 12 replaceAll("w", "W") |
LazyList懒集合
第一次访问元素时才会把这个元素增加到集合中;
LazyList生成的元素会缓存,以备以后获取,确保每个元素只生成一次。
1 | //第1种生成 |
有界的LazyList
:
1 | scala> def to(head: Char, end: Char): LazyList[Char] = (head > end) match { |
一元集合
- option集合:判断一个值存在
some
,或者不存在null
。 - 任何操作都只能应用于
Some
,不会用到None
.
1 | scala> def divide(amt: Double, divisor: Double): Option[Double] = { |
- 判断空
List
:
1 | scala> val odds = List(1, 3, 5) |
- 类型安全的过滤,不会导致
null
异常。
1 | scala> val lowercase = Some("risible") |
1 | scala> def nextOption = if (util.Random.nextInt > 0) Some(1) else None |
Try集合
1 | scala> def loopAndFail(end: Int, failAt: Int): Int = { |
Future集合
scala代码在JVM上执行,同时也在java的线程中执行;
调用future
并提供一个函数会在一个单独线程中执行该函数,而当前线程仍继续操作。
1 | scala> import concurrent.ExecutionContext.Implicits.global |
同步(阻断当前线程):concurrent.Await.result
取一个线程和最大等待时间,等待时间内线程完成就返回结果,否则异常。
1 | scala> import concurrent.duration._ |