Spark基础-列表的使用

List
object TestList {
  val fruit=List("apples","oranges","pears")
  val nums=List(2,34,4,5)
  val shz3={
    List(	
        List(1,2,34,4),
        List(2,3,4.45),
        List(2,1,4,5))  
  }
  val emp=List()
}

列表和数组有点相似,但是有两个根本的区别:1、列表是不可变的,列表的每个元素不能通过赋值进行改变。2、列表的结构是递归的(可以认为是链表),而数组不是。
List同一个列表内的元素都必须是相同类型。元素为T的列表写为List[T],如果以上代码全部都写全是如下的方式:

  val fru:List[String]=List("apples","oranges","pears")
  val nus:List[Int]=List(1,2,3,4)
  val sh3:List[List[Int]]=List(
      List(2,3,4),
      List(34),
      List(12,3,4,5)
      )
   val empty:List[String]=List()

scala的List类型是协变的,意思是对于每一组类型S和T,如果S是T的子类型,那么List[S]也是List[T]的子类型。List[Noting]是任何类型的子类型。
构建列表的基础单元只有两个:Nil和::。Nil表示空列表,::表示追加元素,事实上我们定义List(…)的方式最终都会转化成定义好的包装方法::。如上例最终转化后:

  val fruit="apples"::("oranges"::("pears"::Nil))
  val nums=2::(34::(4::(5::Nil)))
  val shz3=(1::(2::(34::(4::Nil))))::
  (2::(3::(4::(45::Nil))))::
  (2::(1::(4::(5::Nil))))::Nil 
  val emp=Nil

要注意::是右结合的函数。
List的基本操作符:
head:头元素。
tail:尾元素。
isEmpty:列表是否为空。
我们对Nil使用head方法

scala> Nil.head
java.util.NoSuchElementException: head of empty list
  at scala.collection.immutable.Nil$.head(List.scala:420)
  ... 33 elided

会返回一个异常。
scala同样有自己的排序方法,srotBy意思是按照什么元素进行排序
nus.sortBy(x=>x),一个简单的方式,意思是来一个元素就按照本身进行排序。
对于表达式val fruit=List(“apples”,“oranges”,“pears”)我们可以把他拆解开来:

scala> val List(f,r,t)=fruit
f: String = apples
r: String = oranges
t: String = pears

List(f,r,t)匹配长度为3的列表,并将三个元素分别绑定到模式变量f,r,t中。如果我们不知道列表中有多少变量,更好的方式是使用::来匹配

scala> val f::r::t=fruit
f: String = apples
r: String = oranges
t: List[String] = List(pears)

这种方式的好处是即使我们不知道List有几个变量依然可以拿到值,如果我们采用前一种方式,只取两个值会报如下错误:

scala> val List(f,r)=fruit
scala.MatchError: List(apples, oranges, pears) (of class scala.collection.immuta
ble.$colon$colon)
  ... 33 elided

和方法::类似的操作符还有:::。不同的是 :::接收的是两个列表参数。

scala> List(1,2):::List(3,4)
res1: List[Int] = List(1, 2, 3, 4)
scala> List():::List(21,3,4,4,5)
res2: List[Int] = List(21, 3, 4, 4, 5)

同样的:::也是右结合的。

获取列表长度:length

scala> (List(2,3,4,5):::List(3)).length
res6: Int = 5

访问列表:init和last
last只要List尾

scala> List(1,2,3,4).last
res7: Int = 4

init除了尾以外所有List成员。

scala> List(1,2,3,4).init
res8: List[Int] = List(1, 2, 3)

列表反转reverse

scala> List(1,2,3,4).reverse
res9: List[Int] = List(4, 3, 2, 1)

操作符take、drop、splitAt
scala> List(1,2,3,4).take(2)
res10: List[Int] = List(1, 2)

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

scala> List(1,2,3,4) splitAt 3
res12: (List[Int], List[Int]) = (List(1, 2, 3),List(4))
选择操作符apply和indices
apply任意位置选取元素,下标从0开始
scala> List(1,2,3,4) apply 3
res13: Int = 4
indices返回List的有效下标:
scala> List(1,2,3,4).indices
res15: scala.collection.immutable.Range = Range(0, 1, 2, 3)
列表扁平化flatten
scala> List("apples","pears").flatten
res16: List[Char] = List(a, p, p, l, e, s, p, e, a, r, s)

列表拉链操作,zip
scala> List(1,2,3,4) zip List("a","b","c","d")
res17: List[(Int, String)] = List((1,a), (2,b), (3,c), (4,d))
这个操作注意以少为准,意思是以两个列表少的为主,如:
scala> List(1,2,3,4) zip List("a","b","c","d","e")
res18: List[(Int, String)] = List((1,a), (2,b), (3,c), (4,d))

scala> List(1,2,3,4) zip List("a","b","c")
res19: List[(Int, String)] = List((1,a), (2,b), (3,c))
我们可以看到第一个操作只做了四个,因为最少的是List(1,2,3,4)只有四个元素,所以出了四个元素的list集合,第二操作因为最少的是后面只有三个,所以zip的结果只产生了三个List元素。
一个最快速的与其自己的下标拉链的方法:ZipWithIndex
scala> 
val ll=List("apples","pears","bananas","eggs").zipWithIndex
ll: List[(String, Int)] = List((apples,0), (pears,1), (bananas,2), (eggs,3))
我们可以看到拿了下标直接和自己本身形成了新的List。

对应的解拉链:unzip
scala> ll.unzip
res23: (List[String], List[Int]) = (List(apples, pears, bananas, eggs),List(0, 1
, 2, 3))
这个操作也注意需要首先进行zip,然后才能unzip。

List列表的toString和mkString
以元素的形式显示列表
scala> List("as","bv","ssd").toString
res25: String = List(as, bv, ssd)
mkString有三个参数,使用什么做头尾,并且用什么分割。
scala> List("as","bv","ssd").mkString("[",":","]")
res27: String = [as:bv:ssd]
如果什么都不放
scala> List("as","bv","ssd").mkString
res28: String = asbvssd
可以放一个参数,如果一个参数就被识别为分割符:
scala> List("as","bv","ssd").mkString(",")
res31: String = as,bv,ssd

列表转化:iterator、toArray、copyToArray
我们可以在数组和列表间相互做数据转化,可以使用List的toArray和array的toList方法:
scala> val tList=List("l","i","s","t")
tList: List[String] = List(l, i, s, t)

scala> val arr=tList.toArray
arr: Array[String] = Array(l, i, s, t)

我们看到arr已经是一个Array类型。
还有一个方法可以把List列表的元素一次复制到目标数组的指定位置。
使用的语法:List(…) copyToArray(Array[…],下标)
把List放到Array中,从第几位开始。
scala> val arr=Array(1,2,3,4,5,5,6,7,8)
arr: Array[Int] = Array(1, 2, 3, 4, 5, 5, 6, 7, 8)

scala> List(1,2,3) copyToArray(arr,2)

scala> arr
res38: Array[Int] = Array(1, 2, 1, 2, 3, 5, 6, 7, 8)
步骤首先定义一个array,然后在使用copyToArray。
如果没有预先定义,使用另一种方式使用。返回结果仔细观察
scala> val a=List(1,2,3) copyToArray(new ArrayInt,2)
a: Unit = ()
给出的类型是Unit此时虽然操作成功,但是没有返回结果。因为copyToArray返回结果给了Array本身不返回值。
可以通过迭代iterator访问:
scala> val it=List(“a”,“b”,“c”,“d”).iterator
it: Iterator[String] = non-empty iterator
scala> it.next
res40: String = a
scala> it.next
res41: String = b

List的高阶方法:
列表做映射:map、flatMap、foreach
map对list列表的每个元素使用某种算法进行操作
List(…)map(函数)

scala> List(2,3,45,6,3.23)map(x=>x+1)
res43: List[Double] = List(3.0, 4.0, 46.0, 7.0, 4.23)

x=>x+1表示的意思是进来一个元素就对他使用x+1这个动作。这个动作可以使用占位符简写。

scala> List(2,3,45,6,3.23)map(_+1)
res44: List[Double] = List(3.0, 4.0, 46.0, 7.0, 4.23)

同样的还有一些示例操作

scala> List("dfdf","qweqwr","qwewqr","dfdsg","gehhr").map(_.length)
res45: List[Int] = List(4, 6, 6, 5, 5)
scala> List("dfdf","qweqwr","qwewqr","dfdsg","gehhr").map(_.toList.reverse.mkString)
res46: List[String] = List(fdfd, rwqewq, rqwewq, gsdfd, rhheg)

一个和map非常类似的动作flatMap,但是这里不同的是flatMap会进行扁平化的操作,扁平化就是把所有元素打散的操作。在观察两个操作:

scala> val test=List("ddfs","sdf")
test: List[String] = List(ddfs, sdf)

scala> test map(_.toList)
res51: List[List[Char]] = List(List(d, d, f, s), List(s, d, f))

scala> test flatMap(_.toList)
res52: List[Char] = List(d, d, f, s, s, d, f)

首先所有元素经过flatMap首先扁平化,所有元素都别打散,把每个字母都拆开,最后才传递给toList形成一个新的List

一个复杂的应用:
结合了range、flatMap、map的综合应用:

scala> 
val result=List.range(2,7) flatMap(i=>List.range(1,i)map(j=>(i,j)))
result: List[(Int, Int)] = List((2,1), (3,1), (3,2), (4,1), (4,2), (4,3), (5,1),
 (5,2), (5,3), (5,4), (6,1), (6,2), (6,3), (6,4), (6,5))

看一下这段的意义:首先List调用了range方法,是创建一个区间列表的方法,表示创建2 util 7的List也就是没有7,结果交给flatMap,flatMap内的i表示过来的任意一个值,后面的List.range(1,i)表示产生一个List,是1 until i的区间,产生的每一个值进行map操作,map内的j表示来的任意一个值,输出最开始的i和和现在的值j。
这样的列表可以使用for循环:

scala> 
val result=for(i<-List.range(2,7);j<-List.range(1,i))yield(i,j)
result: List[(Int, Int)] = List((2,1), (3,1), (3,2), (4,1), (4,2), (4,3), (5,1),
 (5,2), (5,3), (5,4), (6,1), (6,2), (6,3), (6,4), (6,5))

foreach对每一个元素进行应用,整个操作返回值是Unit,也就是没有返回值返回,我们要做的操作返回的结果都在foreach内。

scala> var sum=0
sum: Int = 0
scala> List(1,2,3,4,5).foreach(sum+=_)

scala> List(1,2,3,4,5).foreach(x=>sum+x)

scala> sum
res56: Int = 15

我们可以看到两种写法在运行是没有结果,但是把sum的加操作执行了,sum的值发生了改变。

过滤操作符:filter、partition、find、takeWhile、dropWhile、span。

scala> List(1,23,4,5,6,7,87).filter(_%2==0)
res57: List[Int] = List(4, 6)
返回一个条件为真的列表
scala> List(1,23,4,5,6,7,87).partition(_%2==0)
res58: (List[Int], List[Int]) = (List(4, 6),List(1, 23, 5, 7, 87))
返回两个列表,一个真一个假。

scala> List(1,23,4,5,6,7,87).find(_%2==0)
res59: Option[Int] = Some(4)
返回满足条件的第一个元素。

scala> List(1,23,4,5,6,7,87).takeWhile(_%2!=0)
res62: List[Int] = List(1, 23)
返回列表连续满足后面条件的列表。

scala> List(1,23,4,5,6,7,87).dropWhile(_%2!=0)
res63: List[Int] = List(4, 5, 6, 7, 87)
删除连续满足条件的列表。
列表排序操作:sortWith
scala> List(1,23,4,5,6,7,87).sortWith(_>_)
res64: List[Int] = List(87, 23, 7, 6, 5, 4, 1)

表示按照降序排列,要习惯这种占位符的写法,简便很多
_>_正常写是(x,y)=>x>y,表示来两个数,按照从打到小顺序排列

最后做一个总结,方法和意义如下:
备注:List方法总结
1 def +(elem: A): List[A]
前置一个元素列表
2 def ::(x: A): List[A]
在这个列表的开头添加的元素。
3 def :::(prefix: List[A]): List[A]
增加了一个给定列表中该列表前面的元素。
4 def ::(x: A): List[A]
增加了一个元素x在列表的开头
5 def addString(b: StringBuilder): StringBuilder
追加列表的一个字符串生成器的所有元素。
6 def addString(b: StringBuilder, sep: String): StringBuilder
追加列表的使用分隔字符串一个字符串生成器的所有元素。
7 def apply(n: Int): A
选择通过其在列表中索引的元素
8 def contains(elem: Any): Boolean
测试该列表中是否包含一个给定值作为元素。
9 def copyToArray(xs: Array[A], start: Int, len: Int): Unit
列表的副本元件阵列。填充给定的数组xs与此列表中最多len个元素,在位置开始。
10 def distinct: List[A]
建立从列表中没有任何重复的元素的新列表。
11 def drop(n: Int): List[A]
返回除了第n个的所有元素。
12 def dropRight(n: Int): List[A]
返回除了最后的n个的元素
13 def dropWhile(p: (A) => Boolean): List[A]
丢弃满足谓词的元素最长前缀。
14 def endsWith[B](that: Seq[B]): Boolean
测试列表是否使用给定序列结束。
15 def equals(that: Any): Boolean
equals方法的任意序列。比较该序列到某些其他对象。
16 def exists(p: (A) => Boolean): Boolean
测试谓词是否持有一些列表的元素。
17 def filter(p: (A) => Boolean): List[A]
返回列表满足谓词的所有元素。
18 def forall(p: (A) => Boolean): Boolean
测试谓词是否持有该列表中的所有元素。
19 def foreach(f: (A) => Unit): Unit
应用一个函数f以列表的所有元素。
20 def head: A
选择列表的第一个元素
21 def indexOf(elem: A, from: Int): Int
经过或在某些起始索引查找列表中的一些值第一次出现的索引。
22 def init: List[A]
返回除了最后的所有元素
23 def intersect(that: Seq[A]): List[A]
计算列表和另一序列之间的多重集交集。
24 def isEmpty: Boolean
测试列表是否为空
25 def iterator: Iterator[A]
创建一个新的迭代器中包含的可迭代对象中的所有元素
26 def last: A
返回最后一个元素
27 def lastIndexOf(elem: A, end: Int): Int
之前或在一个给定的最终指数查找的列表中的一些值最后一次出现的索引
28 def length: Int
返回列表的长度
29 def map[B](f: (A) => B): List[B]
通过应用函数以g这个列表中的所有元素构建一个新的集合
30 def max: A
查找最大的元素
31 def min: A
查找最小元素
32 def mkString: String
显示列表的字符串中的所有元素
33 def mkString(sep: String): String
显示的列表中的字符串中使用分隔串的所有元素
34 def reverse: List[A]
返回新列表,在相反的顺序元素
35 def sorted[B >: A]: List[A]
根据排序对列表进行排序
36 def startsWith[B](that: Seq[B], offset: Int): Boolean
测试该列表中是否包含给定的索引处的给定的序列
37 def sum: A
概括这个集合的元素
38 def tail: List[A]
返回除了第一的所有元素
39 def take(n: Int): List[A]
返回前n个元素
40 def takeRight(n: Int): List[A]
返回最后n个元素
41 def toArray: Array[A]
列表以一个数组变换
42 def toBuffer[B >: A]: Buffer[B]
列表以一个可变缓冲器转换
43 def toMap[T, U]: Map[T, U]
此列表的映射转换
44 def toSeq: Seq[A]
列表的序列转换
45 def toSet[B >: A]: Set[B]
列表到集合变换
46 def toString(): String
列表转换为字符串

想了解更多大数据的小伙伴欢迎加群947967114

猜你喜欢

转载自blog.csdn.net/AiMaEdu/article/details/83857208