拉链扩展
zip函数将传进来的两个参数中对应位置上的元素组成一个pair数组,如果其中一个参数元素比较长,那么多余的参数会被删除
zipAll函数和zip函数类似,但是如果其中一个元素的个数比较少,那么江永默认的元素填充
zipWithIndex函数将元素和其所在的位置索引组成一个pair
该方法把集合中每个元素和该元素的索引进行一个拉链操作
upzip函数可以键一个元组的列表转换成一个列表的元组
列表List
列表中的元素类型不可以不同
列表是有序的
不可变列表
不可变列表的构造
不可变的序列,import scala.collection.immutable._
空列表 可以使用Nil构建一个空列表 val empty = Nil 也可以使用空元素构建一个空列表 val empty : List[Nothing] = List() val fruit=List("apples","oranges","pears") val dig3 = List( List(1,0,0), List(0,1,0), List(0,0,1) ) val empty =List() 所有的列表可以看做是有两个基础构造块Nil和中缀操作符::构成 ,::表示从列表前段扩展 在scala中流标要么为空(Nil表示空列表)要么是一个head元素加上一个tail列表 9 ::List(5,2) :: 操作符是将给定的头和尾创建一个新的列表 注意: ::操作符是右结合的,如 9 :: 5 :: 2 :: Nil相当于9 :: (5 ::(2 ::Nil)) val fruit ="apples" :: ("organes" :: ("pears" :: Nil)) val diag3 = (1 :: (0 :: (0 :: Nil))) :: (0 :: (1 :: (0 :: Nil))) :: (0 :: (0 :: (1 :: Nil))) :: Nil val nums=1::(2::(3::(4::Nil))) val nums = 1 :: 2 :: 3 :: 4 会报错 val nums =1 :: 2 :: 3 :: 4 :: list0 :: Nil 列表中的元素可以是不同类型
列表的访问
val nums = 1 :: 2 :: 3 :: 4 :: list0 :: Nil nums(1) nums(3)
列表的遍历
单个集合的各种遍历方式 val lst = List(1,2,3,4,5) list.foreach{x=>print(x+",")} foreach遍历,传统遍历方式 var temp = list.map{ x => x+1} 与foreach的区别是返回值为List var temp =lst.reduceLeft((sum,i)->sum +i) 返回值类型是一个与集合相同的Int var temp2 =lst.foldLeft(List[Int]())((x,y)=>x::y) 返回值是自定义类型 fold类函数还可以写成 : \ , / : 代码精简不少,但是可读性降低了 var temp3 = (List[Int]()/:lst){(m,c)=?c::m} 实现反转
列表的追加
创建一个不可变集合 val lst1 = List(1,2,3) 将0插入到lst1前面生成一个新的list :: 和 +: 右结合 :: 为右结合操作符 将元素追加到集合开头 val lst2 = 0 :: lst1 val lst3 = lst1.::(0) val lst4 = 0 +: lst1 val lst5 = lst1.+:(0) 将一个元素添加到lst1的后面产生一个新的集合:+ 左结合 val lst6 = lst1 :+ 3 val lst0 = List(4,5,6) 将两个集合合并成一个新的list val lst7 = lst1++lst0 将lst1插入到lst0前面生成一个新的集合 val lst8 = lst1 ++: lst0 将lst0插入到lst1前面生成一个新的集合 val lst9 = lst1.:::(lst0)
列表的基本操作
对列表的操作可分为三种
head返回列表的第一个元素
tail返回除了第一个元素之外的所有元素组成的列表
isEmpty返回列表是否为空
注意:tail head 作用在空列表上会报错
val list0 = List(1,2,3)
val list1= List(4,5,6)
head返回列表第一个元素
list0.head // Int = 1
tail返回除了第一个元素之外的其他元素,以列表的方式返回
list0.tail //List[Int]= List(2,3)
isEmpty:判断列表是否为空,为空时返回true
list0.isEmpty //Boolean =false
concat:连接列表,返回一个新的集合
List.concat(list0,list1) //List[Int]=List(1,2,3,4,5,6)
fill:使用个数相同的元素创建一个列表
List.fill(10)(2) //重复次数10,重复元素2
reverse:将列表顺序反转,返回一个新的集合
list0.reverse
求列表长度
List(1,2,3).length
列表常用方法
与head tail对应的list init val abce=List('a','b','c','d','e') abce.last abce.init 反转列表 abce.reverse tail init的泛化 提取列表的前n个元素 abce take 2 丢弃列表的前n个元素怒 abce drop 2 abce palitAt 2 List(abce take 2,abce drop 2) 拉链操作 abce zip list(1,2,3,4,5)
列表的模式拆分
列表可以使用模式匹配进行拆分
val fruit =List("apples","oranges","pears") 给出的元素个数于列表的元素个数一致,否则会报错 val List(a,b,c)=fruit 在元素的个数不可知的情况下,最好使用::匹配 val a::b::rest=fruit 合并操作 List(1,2) ::: List(3,4,5) List(1,2):::List(3,4,5):::List(6,7,8) List(1,2):::(List(3,4,5):::List(6,7,8))
列表的高阶方法
映射:map ,flatMap ,foreach List(1,2,3).map(_+1) val words=List("the","quick","brown","fox") words.map(_.lenth) word map (_.toList.reverse.toString) words map (_.toList.reverse.mkString) words flatMap(_.toList) var sum=0 List(1,2,3,4,5,6) foreach (sum+=_) 过滤filter,partition,find,takeWhile,dropWhile,span List(1,2,3,4,5) filter (_%2==0) words filter (_.length == 3) List(1,2,3,4,5) partition (_ % 2 ==0) List(1,2,3,4,5)find(_%2==0) List(1,2,3,4,5)find(_<=0) List(1,2,3,-4,5)takeWhie(_ >0) words dropWhiel(_ startWith "t") List(1,2,3,-4,5) span (_>0) 排序sortWith words.sortWith(_.length > _.length)
可变列表
创建一个可变列表初始有三个元素1,2,3 val lst0 = ListBuffer[Int](1,2,3) 创建一个空的可变列表 val lst1 = new ListBuffer[Int] 向lst1中追加元素,没有生成新的集合 lst1 +=4 将lst1中的元素追加到lst0中,没有生成新的集合 lst0 ++= lst1 将lst0和lst1合并成一个新的ListBuffer:生成了一个新的结合 val lst2=lst0 ++ lst1 将元素追加到lst0后面生成一个新的集合 val lst3 =lst0 :=5
set
无序,不可重复
创建集合
不可变集合
val set = new HashSet[Int]() 可以使用加号追加元素 val set1=set+1 set集合中不会出现重复的元素 val set2=set1 ++ Set(1,2,3) val set3=set(1,2,3,4,5,6) set集合中的元素也是无序的
可变集合
val mutableSet =Set(1,2,3) //scala.collection.mutable.HashSet 创建一个可变的HashSet val set1=new mutable.HashSet[Int]() 向hashset中添加元素 set1+=2 add等价于+= 删除一个元素,如果删除的元素对象不存在,则不生效,也不会报错 set1 -=5 set1.remove(2)
集合的基本操作
scala集合中有三个基本操作
head 返回一个集合的第一个元素
tail 返回一个集合,包含处了第一个元素的其他元素
isEmpty在集合为空的时候返回true
对于scala集合的任何操作都可以使用这三个基本操作来表达
val site = Set("1000phone","Google","baidu") val nums:Set[Int]=Set() print("第一个网站是"+site.head) print("最后一个网站是"+site.tail) print("产看列表是否为空"+site.isEmpty) print("查看nums是否为空"+nums.isEmpty)
查找集合中的最大元素和最小元素,可以使用Set.min方法来查找集合中的最小元素,使用Set.max方法来查找集合中的最大元素
val num = Set(5,6,9,20,30,45) set集合遍历 for(x<-num){ print(x) } 查找集合中最小元素与最大元素 print(num.min) print(num.max)
两个set之间的常用操作
你可以使用++ 运算符或者Set.++()方法来连接阿玲哥集合,如果元素有重复,就会移除重复的元素
val site1 = Set("10000phone","google","baidu") val site2 = Set("fackbook","tabobao") ++作为运算符使用 var site = site1 ++ site2 site = site1.++(site2)
交集
val num1=Set(1,2,3,4,5,6) val num2=Set(33,4,5,677,8) 交集 print(num1.&(num2)) print(num1.intersect(num2))
val set1=Set(1,2,34,5,6) val set2=Set(3,4,,56,6) contains:是否包含某一元素,包含返回true,否则返回false set1.contains(10) &:交集运算 set1 * set2 set1.intersect(set2) &~:差集运算 set1 &~ set2 set1.diff(set2) union并集运算 count计算满足指定条件的集合元素个数 val fun=(x:Int)=> x>10 set.count(fun) iterator获得一个迭代器,可以用于遍历集合 val it =set1.iterator while(it.hasNext){ print(it.next()) } size返回集合元素的数量, splitAt将集合产分成两个容器,第一个由前n个元素组成,第二个由剩下的与元素组成 set1.splitAt(5) 返回一个元组 take返回前n个元素 takeRight返回后n个元素 可以使用to{type}快速转换为其他集合类型
集合的应用
集合的重要函数
基本上集合中都可以使用极个别使用不上 spark中常用集合Array List 元组 Map Set map遍历集合处理集合中的数据并返回一个全新集合 filter遍历集合提供一个函数指定过滤的规则,对集合中数据进行过滤,满足需求的会被过滤出来形成一个新的集合 聚合函数sum将集合中每一个元素相加求和最终和(具备可加性) --->数值 max和min最大值和最小值 foreach遍历集合主要是打印集合中的数据(也可以是操作集合中的数据,但是不出新集合-->输出 sorted排序-->升序 降序,可以考虑reverse反转 sortwith需要传入比较参数,这个参数比较会决定升序还是降序 第一个参数>第二个参数,降序 第一个参数<第二个参数 升序 这些方法和array和list基本上都可以使用, mapset选择使用,元组也是选择使用 Flatten可以将存储在集合内部的集合压平 val list:List[List[Int]]=List(List(1,2,3),List(4,5,6),List(7,8,9)) val flatten:List[Int] =list.flatten set集合中提供了特殊的操作 交集,并集和差集 val num1 =Set(3,5,6,7,2) val num2 =Set(3,4,5,6,7,8) 交集 print(num1.intersect(num2)) 并集 print(num1.union(num2)) 差集 print(num1.diff(num2)) forall对集合中的元素条件进行过滤,只有当所有元素都满足要求时,才会返回true,否则返回false val list1=List(1,2,3,4,5) val bool:Boolean=list1.forall(_<3) partition分区 scala中只能魔力,spark中是可以做到这个分区 根据传入的函数,将使数据吸入到不同的存储位置中 val list2=List(1,2,3,4,5,6) 返回的是一个元组 val tuple:(List[Int],List[Int])=list2.partition(_%2==0) val list2_1=tuple._1 聚合函数 fold求和比较特殊,需要两个参数,一个是默认值,另一个是计算逻辑 当前fold是典型的颗粒化 val list3=List(1,2,3,4,5) 计算 现在是属于单线程,使用par的时候会出现多线程状态 val sum = list3.fold(2)((res,n)=>res+n) print(sum) reduce直接求和,通过计算逻辑,进行,集合中数据的计算 val list4=list(1,2,3,4,5,6) reduce也有两个变种reduceleft和reduceright
并行集合
scala为了充分使用多和cpu,提供了并行集合(有别与前面的串行集合)用于多核环境的并行计算
主要用到的算法有:
Divide and conquer: 分治算法,scala通过splitters combiners等抽象层来实现,主要原理是将计算工作分解很多任务,分发给一些处理器去完成
并将他们的处理结果合并,返回
work stealin 算法,主要用于任务调度负载均衡(load-balancing_通俗点,完成所有的任务之后,返现其他人的任务还没做完,主动(或者被安排)帮他人一起干,这样达到尽早干完的目的
打印1-5
(1 to 5).foreach(println(_)) println() (1 to 5).par.foreach(println(_))
查看并行集合中访问元素的线程
val result1=(0 to 10000).map{case _ => Thread.currentThread.getName}.distinct val result2=(0 to 10000).par.map{case _ => Thread.currentThread.getName}.distinct
wordcount
单词统计 数据 val line = List("hello tom hello jerry","hello xiaobai hello","hello tom") 将得到的数据进行处理 flaMap -->flatten+Map具备在遍历处理数据的同时,将数据进行扁平化处理 在处理数据的时候一定要返回一个集合 val words:List[String] = line.flatMap(_.split(" ")) 可以仿照MR中map阶段对单词进行拼接形成kv键值对,单词,1 val tuples:List[(String,Int)]=words.map((_,1)) MR中的kv键值对会发送到reduce然后会出现相同的key 为一组计算一次reduce 因为处理的是单词,仿照MR中的reduce端处理逻辑,形同的key会提供groupBy根据传入的参数进行分组 返回值是一个map val grouped:Map[String,List[(String,Int)]]=tuples.groupBy(_._1) map的组成是key是单词,value是具体单词对应元组,其中元组使用list存储 此时只需要知道key所对应value中list元素的个数,就可以知道当前单词的个数了 mapValues是处理map集合中value的值,只操作value,原则是对应key的value值,返回值是一个map,key是原有的key,value是计算结果之后的value val sumed:Map[String,Int] =grouped.mapValues(_.size) val list: List[(string,Int)]=sumed.toList sortBy分为两种,一种是scala版本,另一种是spark版本 scala版本在没有使用隐式转换自定义的前提下,sortBy只能升序,不能降序 spark版本中的sortBy有两个参数,一个是根据谁来排序,第二个参数是Boolean类型true是升序,false是降序 参数是一个比较原则 val sorted:List[(String,Int)]=list.sortBy(_._2) topN降序排序 val top1=sorted take 1
java和scala集合的互操作
scala中的集合和java中集合互相转换,引用一个包 import scala.collection.JavaConverters._ val list:java.util.List[Int]=List(1,2,3,4,5).asJava 将scala集合转换为java集合 val buffer:mutable.Buffer[Int] = list.asScala 将java集合转换为scala toXXX 转换成你要的集合即可,---->XXX是集合的名字例如Array