Scala的列表结构可以理解为一个样例类,因为它不需要使用new方法,例如:
scala> val a = List("a","b","c")
a: List[String] = List(a, b, c)
除了这种方法构建列表外,还可以使用::符号构建
scala> val t = "a" :: "b" :: "c" :: Nil
t: List[String] = List(a, b, c)
其中Nil表示空列表,::符号表示在列表前面追加元素,所以如果没有后面的Nil,Scala就会报错。
scala> val t = "a"::"b"::"c"
<console>:7: error: value :: is not a member of String
val t = "a"::"b"::"c"
列表不同于数组Array,它是链表结构。并且列表元素必须要是同样的类型,如果列表里混用其它类型,那么它们的类型默认为Any类。所有类型的父类。
scala> val b = List("a",'b')
b: List[Any] = List(a, b)
有趣的一点在于,如果类型S是类型T的子类,那么List[S]也是List[T]的子类。这也是为什么下面的例子可以成立,因为空列表List[Nothing]是所有类型的子类,那么也是List[T]的子类型。
scala> val c:List[Int] = List()
c: List[Int] = List()
scala> List()
res5: List[Nothing] = List()
Scala的列表核心是三个方法:head(返回首元素),tail(除首元素以外的元素),isEmpty(判断是否为空)。
scala> val a = List(1,2,3)
a: List[Int] = List(1, 2, 3)
scala> a.head
res0: Int = 1
scala> a.tail
res1: List[Int] = List(2, 3)
scala> a.isEmpty
res2: Boolean = false
Scala的列表可以利用模式匹配实现和Python一样的解包
scala> val t = List(1,2,3)
t: List[Int] = List(1, 2, 3)
scala> val List(a,b,c) = t
a: Int = 1
b: Int = 2
c: Int = 3
scala> a
res3: Int = 1
scala> b
res4: Int = 2
scala> c
res5: Int = 3
当然如果你不确定元素数量的话,可以利用列表构建符号::去匹配元素,没有匹配上的元素都会变成列表赋给rest。
scala> val t = List(1,2,3,4)
t: List[Int] = List(1, 2, 3, 4)
scala> val a::b::rest = t
a: Int = 1
b: Int = 2
rest: List[Int] = List(3, 4)
下面聊下Scala列表的初阶方法和高阶方法,两者的区别仅在于初阶方法不接受函数作为参数传入,高阶可以。
scala> val a = List(1,2,3)
a: List[Int] = List(1, 2, 3)
scala> val b = List(4,5,6)
b: List[Int] = List(4, 5, 6)
scala> a ::: b
res0: List[Int] = List(1, 2, 3, 4, 5, 6)
用模式匹配去看待列表拼接可以理解为:
scala> def concat[T](x:List[T],y:List[T]):List[T] =
| x match {
| case List() => y
| case x :: xs => x :: concat(xs,y)
| }
concat: [T](x: List[T], y: List[T])List[T]
scala> concat(a,b)
res2: List[Int] = List(1, 2, 3, 4, 5, 6)
只不过这里的concat定义的是函数,而不是列表的中缀方法。
scala> a.init
res3: List[Int] = List(1, 2)
scala> a.last
res4: Int = 3
scala> a.map(_+3)
res5: List[Int] = List(4, 5, 6)
foreach和map很类似,不过需要传入的是返回为Unit的函数
scala> var sum = 0
sum: Int = 0
scala> a.foreach(sum += _)
scala> sum
res7: Int = 6
filter则是过滤元素
scala> a.filter(_<2)
res8: List[Int] = List(1)