针对每种类型的容器,Scala都提供了一批相同的方法,只需几个简单的函数调用就可以代替复杂的循环或递归。使用类库提供的标准操作,通常比自己写的循环更加高效;
一、遍历操作:
1、Scala容器的标准遍历方法为foreach方法,该方法的原型为:
def foreach[U](f: Elem=> U) : Unit
2、实例:
object CollOpt extends App {
//遍历
val person=Map("name"->"Lisi","age"->"20","sex"->"man")
//模式匹配遍历
person.foreach(x=>x match {
case (k,v)=>println("k:"+k+" v:"+v)
})
//匿名函数遍历
person.foreach(kv=>println("k:"+kv._1+" v:"+kv._2))
//for循环遍历
for(kv<-person){
println("k:"+kv._1+" v:"+kv._2)
}
for((k,v)<-person){
println("k:"+k+" v:"+v)
}
}
二、映射操作
映射是指通过对容器中的元素进行某些运算来生成一个新的容器;
1、map方法:
map方法将某个函数应用到集合中的每一个元素,映射得到一个新的元素,并返回一个与原容器类型大小都相同的新容器,但是元素的类型可能与原容器元素的类型有所不同;
object MapOpt extends App {
val list=List("spark","scala","hadoop")
//将字符串全转化为大写
val tr_list=list.map(s=>s.toUpperCase)
println(tr_list) //List(SPARK, SCALA, HADOOP)
//将字符串映射成它的长度
val len_list=list.map(s=>s.length)
println(len_list) //List(5, 5, 6)
}
2、flatMap方法
flatMap方法将某个函数应用到容器中的元素时:
(1)对每个元素都会返回一个容器(而不是一个元素)。
(2)把生成的多个容器”拍扁“成为一个容器并返回。
(3)返回的容器与原容器类型相同,但大小可能不同,元素的类型也可能不同。
object FlatMapOpt extends App {
val list =List("hbase","hive","redis")
//val tr_list=list.map(s=>s.toList) //List(List(h, b, a, s, e), List(h, i, v, e), List(r, e, d, i, s))
//val fla_list=tr_list.flatten(s=>s.toList) //List(h, b, a, s, e, h, i, v, e, r, e, d, i, s)
val flat_list=list.flatMap(s=>s.toList) //List(h, b, a, s, e, h, i, v, e, r, e, d, i, s)
}
注意:
flatMap方法=map方法+flatten方法
三、过滤
1、filter方法
filter方法接受一个返回布尔值的函数f作为参数,并将f作用到每个元素上,将f返回真值的元素组成一个新容器返回;
object FilterOpt extends App {
val list=List(23,34,56,33,3)
//val lis=list.filter(s=>s%2==0)
//val lis=list filter(_%2==0)
val lis = list filter {_%2==0}
println(lis) //List(34, 56)
//filterNot方法和filter相反
val lis_not=list filterNot(_%2==0)
println(lis_not) //List(23, 33, 3)
}
2、exists方法
exists方法判断是否存在满足给定条件的元素,返回布尔值;
object ExitsOpt extends App{
val list=List("Hadoop","Scala","Spark")
val s_list=list exists(_ startsWith("H"))
println(s_list) //true
}
3、find方法
find方法返回第一个满足条件的元素,返回值用Option类进行了包装
val list=List("Hadoop","Scala","Spark","Hbase")
val s_list=list find (_ startsWith("H"))
println(s_list) //Some(Hadoop)
四、规约操作
规约操作是对容器的元素进行两两运算,将其”规约“为一个值。
1、reduce方法:
reduce方法接受一个二元函数f作为参数,首先将f作用在某两个元素上并返回一个值,然后再将f作用在上一个返回值和容器的下一个元素上,再返回一个值,依此类推,最后容器中的所有值会被规约为一个值;
object ReduceOpt extends App {
val list=List(3,4,5,6,7)
//将列表元素累加(两种方式)
val l1=list.reduce(_+_) //25
val l2=list.reduce((x,y)=>x+y) //25
//将列表元素连乘(两种方式)
val l3=list.reduce(_*_) //2520
val l4=list.reduce((x,y)=>x*y) //2520
}
注意:reduce方法遍历有序容器默认顺序是从左到右,但是Set无顺序集合,做减法时结果就会不同;
val set1 = Set(1,2,3)
val s1=set1.reduce(_-_)
//打乱顺序变成新集合
val set2 = util.Random.shuffle(set1)
val s2=set2.reduce(_-_)
println(s1) //-4
println(s2) //-2
2、reduceLeft方法,reduceRight方法
reduceLeft方法从左到右进行遍历,reduceRight方法从右到左进行遍历;
object ReduceOpt extends App {
val list=List(3,4,5)
//将列表元素累加(两种方式)
val l1=list.reduceLeft(_-_) //-6
//4-5=-1
//3-(-1)=4
val l2=list.reduceRight(_-_) //4
}
3、fold方法,foldLeft方法,foldRight方法
fold方法是一个双参数列表的函数,第一个参数列表接受一个规约的初始值,第二个参数列表接受与reduce中一样的二元函数参数。
fold方法和reduce方法区别:
(1)reduce方法是从容器的两个元素开始规约;
(2)fold则是从提供的初始值开始规约;
(3)对于无序容器而言,fold方法不保证规约时的遍历顺序,如果要保证顺序,要使用foldLeft和foldRight;
object FoldOpt extends App {
val list =List(1,2,3)
val l1=(list fold 10)(_*_) //fold的中缀调用方法
val l2 = list.fold(10)(_*_)
println(l1) //60
println(l2) //60
val l3=list.foldLeft(10)(_-_) //(((10-1)-2)-3)
val l4=list.foldRight(10)(_-_) //(1-(2-(3-10)))
println(l3) //4
println(l4) //-8
}
//对空容器fold的结果为初始值,而调用reduce则会报错
val list2=List.empty
val ll=list2.fold(10)(_-_) //10
//val ll2=list2.reduce(_+_) //报错
五、拆分操作
拆分操作是把一个容器里的元素按一定的规则分割成多个子容器,假设原容器为C[T]类型;
1、partition方法:
partition方法接受一个布尔函数,用该行函数对容器元素进行遍历,以二元组的形式返回满足条件和不满足条件的两个C[T]类型的集合。
object PartitionOpt extends App {
val list=List(1,3,4,5,7,8)
val lis=list.partition(_<5)
println(lis) //(List(1, 3, 4),List(5, 7, 8))
}
2、groupedBy方法:
该方法对容器元素进行遍历,将返回值相同的元素作为一个子容器,并于该相同的值构成一个键值对,返回的类型为Map[U,C[T]]的映射;
object GroupedBy extends App {
val list=List(2,3,4,5,6)
val l1=list.groupBy(x=>x%3)
println(l1) //Map(2 -> List(2, 5), 1 -> List(4), 0 -> List(3, 6))
//获取k为2的子容器
println(l1(2)) //List(2, 5)
}
3、grouped方法和sliding方法:
两个方法都将容器拆分为多个与原容器相同的子容器,并返回由这些子容器构成的迭代器,grouped方法按从左到右将容器划分为多个大小为n的子容器,最后一个的子容器大小可能小于n;sliding使用一个长度为n的滑动窗口,从左向右将容器截取为多个大小为n的子容器;
val list=List(2,3,4,5,6)
val l1=list.grouped(2)
println(l1.next())
println(l1.next())
println(l1.next())
println(l1.hasNext)
List(2, 3)
List(4, 5)
List(6)
false
val list=List(2,3,4,5,6)
val l1=list.sliding(2)
println(l1.next())
println(l1.next())
println(l1.next())
println(l1.hasNext)
List(2, 3)
List(3, 4)
List(4, 5)
true