Scala集合常用函数超详细

前言

大家好,我是楚生辉,在未来的日子里我们一起来学习Scala相关的技术,一起努力奋斗,遇见更好的自己!

Scala是一门多范式的编程语言,一种类似java的编程语言,设计初衷是实现可伸缩的语言 、并集成面向对象编程和函数式编程的各种特性。今天着重分享一下集合常用函数相关知识,有需要的小伙伴可以自行获取与学习~

1 集合常用函数

1.1 基本属性和常用操作

  • 说明
    1. 获取集合长度
    2. 获取集合大小,等同于length,但是唯一需要注意的是set里面没有lenth
    3. 循环遍历:最基础的遍历方式
    4. 迭代器:更简便的遍历方式
    5. 生成字符串:让集合变成字符串
    6. 判断是否包含某个元素
  • 案例实操
object TestList {
    def main(args: Array[String]): Unit = {
        val list: List[Int] = List(1, 2, 3, 4, 5, 6, 7)
        //(1)获取集合长度
        println(list.length)
        //(2)获取集合大小,等同于length  set里面没有lenth
        println(list.size)
        //(3)循环遍历
        list.foreach(println)
        //(4)迭代器
        for (elem <- list.itera tor) {
            println(elem)
        }
        //(5)生成字符串,自定义--分隔符
        println(list.mkString("--"))
        //(6)判断是否包含某个元素
        println(list.contains(3))
    }
}

1.2 衍生集合(交集并集反转等)

调用这些方法,可以生成新的集合

  • 说明
    1. 获取集合的头
    2. 获取集合的尾:去掉头,剩下的都是尾
    3. 集合最后一个数据
    4. 集合初始数据:去掉最后一个,前面都叫初始数据
    5. 反转
    6. 取前(后)n 个元素
    7. 去掉前(后)n 个元素
    8. 并集
    9. 交集
    10. 差集
    11. 拉链:把个数相同的整合到一起
    12. 滑窗:定义一个滑动的窗口,把窗口里面的集合选择出来
  • 案例实操
object TestList {
    def main(args: Array[String]): Unit = {

        val list1: List[Int] = List(1, 2, 3, 4, 5, 6, 7)
        val list2: List[Int] = List(4, 5, 6, 7, 8, 9, 10)
        //(1)获取集合的头
        println(list1.head)
        //(2)获取集合的尾(去掉头,剩下的都是尾)
        println(list1.tail)
        //(3)集合最后一个数据
        println(list1.last)
        //(4)集合初始数据(去掉最后一个,前面都叫初始数据)
        println(list1.init)
        //(5)反转
        println(list1.reverse)
        //(6)取前(后)n 个元素
        println(list1.take(3))
        println(list1.takeRight(3))
        //(7)去掉前(后)n 个元素
        println(list1.drop(3))
        println(list1.dropRight(3))
        //(8)并集
        println(list1.union(list2))
        //(9)交集
        println(list1.intersect(list2))
        //(10)差集
        println(list1.diff(list2))
        //(11)拉链 注:如果两个集合的元素个数不相等,那么会将同等数量的数据进行拉链,多余的数据省略不用
        println(list1.zip(list2))
        // List((1,4), (2,5), (3,6), (4,7), (5,8), (6,9), (7,10))

        //(12)滑窗
        list1.sliding(3).foreach(println)   // 3个数一个窗口,步进默认是1
        list1.sliding(2, 5).foreach(println) // 2个数一个窗口,步进为5

        // List(1, 2, 3)
        // List(2, 3, 4)
        // List(3, 4, 5)
        // List(4, 5, 6)
        // List(5, 6, 7)
        // List(1, 2)
        // List(6, 7)
    }
}

1.3 集合计算简单函数

  • 说明
    1. 求和
    2. 求乘积
    3. 最大值
    4. 最小值
    5. 排序

如果集合里面的内容是元组类型,那么默认比较第一个的Ascii码值,如果我们需要比较指定排序的元素,我们就需要定义函数

  • 简单集合案例实操
object TestList {
    def main(args: Array[String]): Unit = {
        val list: List[Int] = List(1, 5, -3, 4, 2, -7, 6)
        //(1)求和
        println(list.sum)
        //(2)求乘积
        println(list.product)
        //(3)最大值
        println(list.max)      
        //(4)最小值
        println(list.min)
        //(5)排序
        
        // 从小到大排序
        println(list.sorted)
        // 从大到小排序
        println(list.sorted.reverse)
        // 按照元素大小排序
        println(list.sortBy(x => x))
        // 按照第二个数据进行从小到大排序
        println(list.sortBy( _._2))
        // 按照元素的绝对值大小排序
        println(list.sortBy(x => x.abs))
      
        // 按元素大小升序排序 <就是从小到大, >就是从大到小
        println(list.sortWith( (x:Int, y:Int) => {x < y} ))
        println(list.sortWith( _ < _ ))
        // 按元素大小降序排序 
        println(list.sortWith((x, y) => x > y))
        println(list.sortWith( _ > _ ))
    }
}

sorted :对一个集合进行自然排序,通过传递隐式的 Ordering

sortBy : 对一个属性或多个属性进行排序,通过它的类型。

sortWith :基于函数的排序,通过一个 comparator 函数,实现自定义排序的逻辑。

  • 复杂集合案例实操
object Test05_Extents {
    def main(args: Array[String]): Unit = {
        val list= List(("a",3),("b",2),("c",8),("d",1),("e",4))

        // 根据元组的第二个数进行筛选出最大值
        println(list.maxBy((tuple:(String,Int))=> tuple._2  ))
        // 简写
        println(list.maxBy( _._2 ))
    }
}

// 输出
(c,8)
(c,8)

1.4 集合计算高级函数

  • 说明

    • 过滤:遍历一个集合并从中获取满足指定条件的元素组成一个新的集合

    • 转化/映射(map):将集合中的每一个元素映射到某一个函数

    • 扁平化 : 拆成每一个具体的元素再整合到一个集合 多用于集合嵌套

    • 扁平化+映射

      注:flatMap 相当于先进行 map 操作,在进行 flatten 操作集合中的每个元素的子元素映射到某个函数并返回新集合

    • 分组(group) : 按照指定的规则对集合的元素进行分组

    • 简化(归约):所有的数据都保持一个状态进行叠加处理,返回值类型是Map类型

    • 折叠:

  • 实操

object TestList {
    def main(args: Array[String]): Unit = {
        val list: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)
        val nestedList: List[List[Int]] = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9))
        val wordList: List[String] = List("hello world", "hello nantong", "hello scala")

        //(1)过滤 选取数据是偶数的数据 是true就保留,是false就舍弃
        println(list.filter( (x:int)=> {x % 2 == 0} ))
        println(list.filter(_ % 2 == 0))

        //(2)转化/映射
        println(list.map(x => x + 1))
        println(list.map(_ + 1))

        //(3)扁平化
        println(nestedList.flatten)

        //(4)扁平化+映射 注:flatMap 相当于先进行 map 操作(进行分隔成数组),进行扁平化操作
        println(wordList.flatMap(x => x.split(" ")))
        println(wordList.flatMap(_.split(" ")))

        //(5)分组 为true的分一组,对于2取余的结果当成组名然后分组 返回值类型是Map类型
        println(list.groupBy(x => x % 2))
        println(list.groupBy( _ % 2))
        println(list.groupBy(x => if (x % 2== 0 ) "偶数" else "基数" ))

        // Map(偶数 -> List(2, 4, 6, 8), 基数 -> List(1, 3, 5, 7, 9))

        // 给定一组词汇,按照单词的首字母进行分组计算
        val list = List("world", "nantong", "scala")
        println(list.groupBy(_.charAt(0)))
    }
}
  • Reduce 方法

    Reduce 简化(归约) :通过指定的逻辑将集合中的数据进行聚合,从而减少数据,最终获取结果。

object TestReduce {
    def main(args: Array[String]): Unit = {
        val list = List(1,2,3,4)
        // 将数据两两结合,实现运算规则
        val i: Int = list.reduce( (x,y) => x-y )
        println("i = " + i)
        // 从源码的角度,reduce 底层调用的其实就是 reduceLeft
        //val i1 = list.reduceLeft((x,y) => x-y)
        // ((4-3)-2-1) = -2
        val i2 = list.reduceRight((x,y) => x-y)
        println(i2)
    }
}
  • Fold 方法

    Fold 折叠:简化的一种特殊情况。存在一个初始值,后面每来一个值,就在后面做聚合

    • 案例实操:fold 基本使用
    object TestFold {
        def main(args: Array[String]): Unit = {
            val list = List(1,2,3,4)
            // fold 方法使用了函数柯里化,存在两个参数列表
            // 第一个参数列表为 : 零值(初始值)
            // 第二个参数列表为: 简化规则
            // fold 底层其实为 foldLeft
            val i = list.foldLeft(1)((x,y)=>x-y)
            val i1 = list.foldRight(10)((x,y)=>x-y)
            println(i)
            println(i1)
        }
    }
    
    • 案例实操:两个集合合并
    object TestFold {
        def main(args: Array[String]): Unit = {
            // 两个 Map 的数据合并
            val map1 = mutable.Map("a"->1, "b"->2, "c"->3)
            val map2 = mutable.Map("a"->4, "b"->5, "d"->6)
            val map3: mutable.Map[String, Int] = map2.foldLeft(map1) 
            {
                (map, kv) => {
                    val k = kv._1
                    val v = kv._2
                    map(k) = map.getOrElse(k, 0) + v
                    map
                }
            }
            println(map3)
        }
    }
    

1.5 普通 WordCount 案例

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

  • 案例实操

object TestWordCount {
    def main(args: Array[String]): Unit = {
        // 单词计数:将集合中出现的相同的单词,进行计数,取计数排名前三的结果
        val stringList = List("Hello Scala Hbase kafka", "Hello Scala Hbase", "Hello Scala", "Hello")
        // 1) 将每一个字符串转换成一个一个单词
        val wordList: List[String] = stringList.flatMap(str=>str.split(" "))
        //println(wordList)
        // 2) 将相同的单词放置在一起
        val wordToWordsMap: Map[String, List[String]] = wordList.groupBy(word=>word)
        //println(wordToWordsMap)
        // 3) 对相同的单词进行计数
        // (word, list) => (word, count)
        val wordToCountMap: Map[String, Int] = wordToWordsMap.map(tuple=>(tuple._1, tuple._2.size))
        // 4) 对计数完成后的结果进行排序(降序)
        val sortList: List[(String, Int)] = wordToCountMap.toList.sortWith {
            (left, right) => {
                left._2 > right._2
            }
        }
        // 5) 对排序后的结果取前 3 名
        val resultList: List[(String, Int)] = sortList.take(3)
        println(resultList)
    }
}

简化操作

object Test05_Extents {
    def main(args: Array[String]): Unit = {
        val stringList = List("Hello Scala Hbase kafka", "Hello Scala Hbase", "Hello Scala", "Hello flink from Scala")
        val wordList = stringList.flatMap(_.split(" "))
        val groupMaps = wordList.groupBy(word => word)
        println(groupMaps)

        // 对分组之后的list取长度的,得到每个单词的个数
        val countMap = groupMaps.map(kv => (kv._1,kv._2.length))
        println(countMap)
        // 将map转化为list并且排序取前三
        val sortList:List[(String,Int)] = countMap.toList.sortWith(_._2 > _._2).take(3)
        println(sortList)
    }
}
// 控制台打印
1.Map(Hbase -> List(Hbase, Hbase), Scala -> List(Scala, Scala, Scala, Scala), flink -> List(flink), kafka -> 		List(kafka), Hello -> List(Hello, Hello, Hello, Hello), from -> List(from))
2.Map(Hbase -> 2, Scala -> 4, flink -> 1, kafka -> 1, Hello -> 4, from -> 1)
3.List((Scala,4), (Hello,4), (Hbase,2))

1.6 复杂 WordCount 案例

存在一些预统计,里面还有一些已经统计好的数据

思路一:直接展开为普通版本,数字是几,就展开多少个

思路二:直接根据预先统计的结果去转换

object Test05_Extents {
    def main(args: Array[String]): Unit = {
        
        val tupleList: List[(String, Int)] = List(
            ("hello", 1),
            ("hello world", 2),
            ("hello scala", 3),
            ("hello spark from scala", 1),
            ("hello flink from Scala", 2),
        )
        // 思路一:根据后面的数字进行拆分,数字是几,就拆分成多少个
        val newStringList = tupleList.map(
            kv => {
                (kv._1 + " ") * kv._2
            }
        )
        val list: List[(String, Int)] = newStringList
            .flatMap(_.split(" ")) // 空格分词
            .groupBy(word => word) // 对单词分组
            .map(kv => (kv._1, kv._2.length)) // 统计单词个数
            .toList.sortWith(_._2 > _._2) //转化为集合并且排序
        
        println(list)
        
        // 思路二:直接基于预统计的结果进行转换。每一个单词都跟后面的数字进行一个元组
        // 1. 将字符串打散为单词并且与后面的个数结合包装成元组
        val preCountList: List[(String, Int)] = tupleList.flatMap(
            tuple => {
                val strings: Array[String] = tuple._1.split(" ")
                strings.map(word => (word, tuple._2))
            }
        )
        println(preCountList)
        // List((hello,1), (hello,2), (world,2), (hello,3), (scala,3), (hello,1), (spark,1), (from,1), (scala,1), (hello,2), (flink,2), (from,2), (Scala,2))
        // 2. 对二元组按照单词进行分组
        val preCountMap = preCountList.groupBy(_._1)
        println(preCountMap)
    
        // 3. 叠加每个单词预统计的数值 只取map的value
        val CountMap = preCountMap.mapValues(
            // 取出List的第二个元素并且进行sum聚合相加
            tupleList => tupleList.map(_._2).sum
        )
        val list1: List[(String, Int)]  = CountMap.toList.sortWith(_._2>_._2)
        println(list1)
        
    }
}

你可能感兴趣的:(学无止境,scala,java,开发语言)