Scala_容器的各种操作

    针对每种类型的容器,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

 

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郝少

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值