Scala 列表(List)

Posted: 2020-03-05  By  vilay  |  Views(17)

1. List

ListScala 中非常重要的一个数据结构,其与 Array(数组) 非常类似,但是 List 是不可变的.

var list = List("vilay","zz")
println(list(0))

由于List是不可变的,所以不能重新赋值

list(0) = "zzzz" //会报错

2. List的特性

同构 (homogeneous):同一个 List 中的所有元素都必须是相同的类型;
协变 (covariant):如果 S 是 T 的子类型,那么 List[S] 就是 List[T] 的子类型,例如 List[String] 是 List[Object] 的子类型。

需要特别说明的是空列表的类型为 List[Nothing]:

scala> List()
res1: List[Nothing] = List()

3. 构建List

所有 List 都由两个基本单元构成:Nil 和 ::(读作”cons”)。即列表要么是空列表 (Nil),要么是由一个 head 加上一个 tail 组成,而 tail 又是一个 List。我们在上面使用的 List(“hadoop”, “spark”, “storm”) 最终也是被解释为 “hadoop”::“spark”:: “storm”::Nil。

scala>  val list01 = "hadoop"::"spark":: "storm"::Nil
list01: List[String] = List(hadoop, spark, storm)

// :: 操作符号是右结合的,所以上面的表达式和下面的等同
scala> val list02 = "hadoop"::("spark":: ("storm"::Nil))
list02: List[String] = List(hadoop, spark, storm)

4. 模式匹配

Scala 支持展开列表以实现模式匹配。

scala>  val list = List("hadoop", "spark", "storm")
list: List[String] = List(hadoop, spark, storm)

scala> val List(a,b,c)=list
a: String = hadoop
b: String = spark
c: String = storm

如果只需要匹配部分内容

scala> val a::rest=list
a: String = hadoop
rest: List[String] = List(spark, storm)

5. 列表操作

基本操作

object ListApp extends App {

var list = List("vilay","zz","pp")

// println(list.isEmpty)  //false 判断列表是否为空

// println(list.head)  //vilay 返回列表第一个元素

// println(list.tail)  //List("zz","PP")   //返回列表中除第一个元素外的所有元素

// println(list.tail.head)  //zz  head tail结合使用

// println(list.init)  //vilay,zz  返回列表除最后一个元素外的所有元素,与tail相反

// println(list.last)  //pp 返回列表最后一个元素,与head相反

// println(list.length)  // 返回列表的长度

// println(list(2))  //根据索引返回列表数据,从0开始索引

// println(list.reverse)  //反转列表
    // println(list.indices)  //Range 0 until 3  返回列表的所有下标

// take  获取前n个元素
// println(list take 2)  //List(vilay, zz)

//drop 删除前n个元素
// println(list drop 1)  //List(zz, pp)

//splitAt 从第几个元素开始拆分
// var newlist = List("vilay","zz","pp","xx","yy")
// println(newlist splitAt 2) //(List(vilay, zz),List(pp, xx, yy))

//flatten flatten 接收一个由列表组成的列表,并将其进行扁平化操作,返回单个列表。
// var newlist = List(List(1,3),List(5,7),List(),List(10))
// println(newlist.flatten)   //List(1, 3, 5, 7, 10)
//多维列表
// var newlist = List(List(List(1,2),List(3,4)),List(List(8,9),List(10,11)))
// println(newlist.flatten)  //List(List(1, 2), List(3, 4), List(8, 9), List(10, 11))

// println(newlist.flatten.flatten)  //List(1, 2, 3, 4, 8, 9, 10, 11)


//zip & unzip 两个 List 执行 zip 操作结果如下,返回对应位置元素组成的元组的列表,unzip 则执行反向操作
// var score = List(20,15,89)

// var scorelist = list zip score

// println(scorelist)

// var unziplist = scorelist.unzip

// println(unziplist)

//toString  toString 返回 List 的字符串表现形式

// println(list.toString)  //

//mkString 如果想改变 List 的字符串表现形式,可以使用 mkString。mkString 有三个重载方法

// // start:前缀  sep:分隔符  end:后缀
// def mkString(start: String, sep: String, end: String): String =
// addString(new StringBuilder(), start, sep, end).toString

// // seq 分隔符
// def mkString(sep: String): String = mkString("", sep, "")

// // 如果不指定分隔符 默认使用""分隔
// def mkString: String = mkString("")

// println(list.mkString)   //vilayzzpp

// println(list.mkString(","))  //vilay,zz,pp

// println(list.mkString("{",",","}"))  //{vilay,zz,pp}

//iterator iterator 方法返回的是迭代器

// val iterator: Iterator[String] = list.iterator
// while(iterator.hasNext) {
//     println(iterator.next)
// }

//vilay
// zz
// pp

//toArray ,toList 数组和List之间互转
// var listarr = list.toArray

// var listlist = listarr.toList

//copyToArray 将List中的元素拷贝到数组中去,如果数组长度不够,尾部的元素不显示
// var score = Array("10","20","30","40")
// list.copyToArray(score,1)
// println(score.toBuffer)   //ArrayBuffer(10, vilay, zz, pp)
}