• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Scala学习(十一)---集合高阶

武飞扬头像
肥大毛
帮助1

1.集合常用方法

class Test_Func {

}
object Test_Func{
  def main(args: Array[String]): Unit = {
    val list = List(1, 2, 3, 4, 5)//定义一个List集合
    val set = Set(6, 7, 8, 9)//定义一个Set集合

    //1.获取集合长度,length方法
    val lengthList = list.length
    //2.获取集合大小,size方法
    val sizeList = list.size
    println(lengthList)
    println(sizeList)

    //3.循环遍历 foreach
    list.foreach(println)

    //4.迭代器遍历 iterator
    val iterator = list.iterator
    while (iterator.hasNext){
      val i = iterator.next()
      println(i)
    }

    //5.生成字符串方法 
    //mkString
    val string = list.mkString

    //6.是否包含元素contains
    val bool = list.contains(2)
    println(bool)
  }
}

学新通

2.衍生集合

衍生集合,顾名思义,在scala中,调用一个方法,原集合保持不变,生成一个新的集合。

   class Test_Change {

}
object Test_Change
{
  def main(args: Array[String]): Unit = {
    val list1 = List(1, 2, 3, 4)
    val list2 = List(4, 5, 6, 7)

    //获取集合的头
    //即获取第一个元素
    val head = list1.head
    println(head)

    //获取集合的尾部
    val tail = list1.tail
    println(tail)

    //获取集合的最后一个元素
    val last = list1.last
    println(last)

    //获取集合初始数据(不包含最后一个)
    val init = list1.init
    println(init)

    //反转
    val reverse = list2.reverse
    println(reverse)
    val reverse1 = (1 to 5).reverse
    println(reverse1)

    //取前(后)n个元素
    val left1 = list2.take(2)//从左边拿2个元素
    println(left1)
    val right1 = list2.takeRight(2)//从右边拿2个元素
    println(right1)

    //去掉前(后)n个元素
    val left2 = list2.drop(2)//从左边拿
    val right2 = list2.dropRight(2)//从右边拿
    
    //并集
    val unionList = list2.union(list1)
    println(unionList)
    
    //交集
    val intersectList = list2.intersect(list1)
    println(intersectList)
    
    //差集
    val diffList = list2.diff(list1)
    println(diffList)

	    //拉链
    //两个集合进行拉链的时候,如果有一个集合元素过多的话,会被扔掉
    val zipList = list2.zip(list1)
    println(zipList)

    //滑窗
    //给定一个数组(-200,50,-10,30,0,-88)求出任意相邻的三个数,乘积最大的是哪三个
    //根据题,以三个元素为一个窗口
    //sliding函数第一个参数为窗口大小,这里为3
    val list3 = List(-200, 50, -10, 30, 0, -88)
    val iterator:Iterator[List[Int]] = list3.sliding(3)
    var result=0;
    for(item<-iterator)
      {
        //product方法是用于算出集合的乘积
        if(item.product>result)
          {
            result=item.product
          }
      }
      println(result)
  }
}

学新通

滑窗运行结果:
学新通
可以看到sliding函数将list3集合分成了四个有三个元素的集合,之后通过product方法对每个集合求乘积,由此来将最大的乘积算出。

3.集合的常用函数

    val list4 = List(1, 2, 3, 4, 5)
    //求和
    val sum = list4.sum
    //求乘积
    val product = list4.product
    //最大值
    val max = list4.max
    //最小值
    val min = list4.min

学新通
过滤
所有的高级函数,都有一个默认的foreach逻辑将集合中的元素作为填写函数的传入参数,得到返回结果。如果为true则保留,如果为false,则删除

    val list = List(1, 2, 3, 5, 6, 8, 9, 10)
    val reList = list.filter((i: Int) => i % 2 == 0)
    println(reList)

map转化结构
可以在map中设定输出结构,来对集合进行转化

 val list2 = list.map((i: Int) => i * 2)
    println(list2)
    val list3:List[(String,Int)] = list.map((i: Int) => ("我是", i))
    println(list3)

扁平化
对于集合嵌套的情况下,使用炸裂函数来将嵌套的集合打散。即将嵌套的集合转换为一个集合。

    val list4 = List(List(1, 2, 3), List(1, 5, 6), List(2, 3, 6))
    val flatten:List[Int] = list4.flatten
    println(flatten)
    //元素必须是可以拆分的集合才能使用扁平化
    //字符串可以看作为char的数组
    val list5 = List("Hello", "王总")
    val flatten1 = list5.flatten
    println(flatten1)
    //将长字符串打散为多个单词
    val list6 = List("hello world", "hello scala", "hello spark")
    //需要将"hello world"转换为List("Hello","world")
    val list8 = list6.map((line: String) => {
      val strings: Array[String] = line.split(",")
      strings.toList
    })
    println(list8)
    val flatten2 = list8.flatten
    println(flatten2)
学新通

flatMap
flatMap方法就是map flatten方法的结合,先将结合转换为设定的结构,之后再通过flatten来对集合进行打散。

    val list9 = list6.flatMap((line: String) => {
      val strings: Array[String] = line.split(",")
      strings.toList
    })
    println(list9)

分组函数group by
将多条数据聚合成一条数据,以groupby函数中的返回值的类型为key的类型

    val list10: List[(Int, Int)] = List((1, 10), (2, 30), (3, 30),(1,11),(2,32))
    val map: Map[Int, List[(Int, Int)]] = list10.groupBy((tuple: (Int, Int)) => tuple._1)

    println(map)

    //以奇偶数来进行分组
    val list11 = List(1, 2, 3, 4, 5, 6)
    val groupByOdd = list11.groupBy((i: Int) => i % 2)
    println(groupByOdd)

归约
归约的用法和mapreduce中的reduce方法大致相同。将集合中的元素进行累加操作。

    //reduce方法返回结果的类型和当前元素的类型一致
    val list12 = List(1, 5, 6, 7, 8)
    //如下函数就是一个归约
    var sum=0
    for(elem<-list12)
      {
        sum =elem
      }
      println(sum)
    //可以使用reduce方法来实现上述代码的逻辑
    //res表示结果,elem表示当前元素
    val i = list12.reduce((res: Int, elem: Int) => res   elem)
    println(i)
    //reduce方法将第一个元素作为初始值进行累加即1 5*2 6*2......
    list12.reduce((res: Int, elem: Int) => res   elem*2)
    //如果使用fold方法,那么会让你手动填写一个初始值
    val i1 = list11.fold(0)((res: Int, elem: Int) => res   2 * elem)
    println(i1)
学新通

归约两个Map

问题引出:归约两个map,将两个map合并,如果两个map中有相同的key,将value值相加.如果不存在,就整个key-value放入map中
方式一:循环

    //使用循环的方法来归约两个map
    for(elem<- map2)
      {
        val key = elem._1
        val value = elem._2
        //如果存在当前key
        if(map1.contains(key))
          {
            map1.update(key,value map1.getOrElse(key,0))
          }
          else
          {
            map1.put(key, value)
          }
      }
    print(map1)
学新通

运行结果:
学新通
方式二:使用归约函数

    //方式二:使用归约函数foldLeft
    //谁调用foldLeft就遍历谁
    //fold和reduce的区别在于fold会设置初始值,而reduce会将第一个数设为初始值
    map2.foldLeft(map1)((res,elem)=>{
      val key = elem._1
      val value = elem._2
      if(res.contains(key))
        {
          res.update(key, value res.getOrElse(key,0))
        }else
        {
          res.put(key, value)
        }
        res
    })
    println(map1)
学新通

运行结果同上。

在第二种方式中,不仅可以归约可变map集合,也可以归约不可变map集合。在归约不可变map集合的时候,会保证线程安全,因为无论归约不可变集合多少次,得到的变量值始终相同,而在归约可变map集合的时候,可变map集合的结果值会随着归约的次数不断累加。

    //归约不可变map集合
    val map3 = Map(("hello", 10), ("scala", 10))
    val map4 = Map(("hello", 10), ("scala", 10), ("java", 20))
    val map5 = map4.foldLeft(map3)((res, elem) => {
      //在归约不可变map的时候,只能调用方法updated
      res.updated(elem._1, elem._2   res.getOrElse(elem._1, 0))
    })
    println(map5)

归约不可变map的时候,需要有一个变量来接收最终归约的结果。

4.WordCount案例练习

需求:将集合中出现的相同的单词,进行计数,取排名前三的结果。

    val stringList = List("hello world", "hello China", "hello liaoning", "hello dalian")
    //调用flatmap方法
    //1.先将每个元素拆分得到单词,之后再将集合打散
    val resList = stringList.flatMap((s) => {
      val strings = s.split(" ")
      strings.toList
    })
    println(resList)

    //2.分组聚合单词
    //以单词本身进行分组聚合
    val aggMap = resList.groupBy((s) => s)
    println(aggMap)

    //3.转换格式
    val wordCountMap = aggMap.map((tuple) => {
      (tuple._1, tuple._2.size)
    })
    println(wordCountMap)

    //使用mapvalues进行优化
    //只能用于元素值是二元组,同时key保持不变,只能修改value的时候
    val wcMap = aggMap.mapValues((value) => (value.size))
    println(wcMap)

    //排序取top3
    val wclist = wcMap.toList
    println(wclist)

    //倒序
    //使用sortBy
    val topres = wclist.sortBy((tuple: (String, Int)) => {
      tuple._2
    })(Ordering[Int].reverse)
    println(topres)

    //使用sortWith
    val restop = wclist.sortWith((left, right) => {
      left._2 > right._2
    })

    println(restop)

    //取前三个元素
    val finres = restop.take(3)
    println(finres)
学新通

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgkiech
系列文章
更多 icon
同类精品
更多 icon
继续加载