Scala-集合函数实践

集合常用函数

object TestCommonOp {

    def main(args: Array[String]): Unit = {
        val list = List(1, 3, 4, 5, 6, 7, 8, 99)
        val set = Set(33, 45, 66, 77)

        // (1)获取集合长度,线性的序列都可以获取到长度
        println(list.length)

        // (2)获取集合大小,几乎有集合类型都可以获取到大小
        println(set.size)

        // (3)循环遍历
        for (elem <- list) {
            println(elem)
        }
        set.foreach(println)

        // (4)迭代器
        for (elem <- list.iterator) {
            println(elem)
        }

        // (5)生成字符串
        println(list)               // List(1, 3, 4, 5, 6, 7, 8, 99)
        println(set)                // Set(33, 45, 66, 77)
        println(list.mkString("-")) // 1-3-4-5-6-7-8-99

        // (6)是否包含
        println(list.contains(1))   // true
        println(set.contains(44))   // false
    }
}

衍生集合

object TestDerivedCollection {

    def main(args: Array[String]): Unit = {

        val list = List(1, 3, 55, 66, 77)
        val list2 = List(1, 44, 55, 88, 99)

        // (1)获取集合的头,一般在有序的集合才用这个
        println(list.head) // 1

        // (2)获取集合的尾(不是头的就是尾)
        println(list.tail) // List(3, 55, 66, 77)

        // (3)集合最后一个数据
        println(list.last) // 7

        // (4)集合初始数据(不包含最后一个)
        println(list.init) // List(1, 3, 55, 66)

        // (5)反转
        println(list.reverse) // List(77, 66, 55, 3, 1)

        // (6)取前(后)n 个元素
        // 取前3个元素
        println(list.take(3)) // List(1, 3, 55)
        // 取出后4个元素
        println(list.takeRight(4)) // List(3, 55, 66, 77)

        // (7)去掉前(后)n 个元素
        // 取去掉前三个之后剩下的
        println(list.drop(3))      // List(66, 77)
        // 取去掉前二个之后剩下的
        println(list.dropRight(2)) // List(1, 3, 55)

        // (8)并集
        println("union: " + list.union(list2)) // union: List(1, 3, 55, 66, 77, 1, 44, 55, 88, 99)
        println(list ++ list2)                 // List(1, 3, 55, 66, 77, 1, 44, 55, 88, 99)

        // Set并集
        val set = Set(1, 3, 55, 66, 77)
        val set2 = Set(1, 44, 55, 88, 99)
        println("set union: " + set.union(set2)) // set union: Set(88, 1, 77, 44, 66, 3, 99, 55)
        println(set ++ set2)                     // Set(88, 1, 77, 44, 66, 3, 99, 55)

        // (9)交集
        println("intersection: " + list.intersect(list2)) // intersection: List(1, 55)

        // (10)差集,求集合独有的元素
        val diff1 = list.diff(list2)
        val diff2 = list2.diff(list)
        println(s"diff1: $diff1")    // diff1: List(3, 66, 77)
        println(s"diff2: $diff2")    // diff2: List(44, 88, 99)

        // (11)拉链,两个集合中元素对应位置组合成为二元组,多出来的去掉
        println("zip1: " + list.zip(list2)) // zip1: List((1,1), (3,44), (55,55), (66,88), (77,99))
        println("zip2: " + list2.zip(list)) // zip2: List((1,1), (44,3), (55,55), (88,66), (99,77))

        // (12)滑窗
        // 得到大小为3的窗口大小,还可以传入步数,默认每次滑动1
        for (elem <- list.sliding(3)) {
            println(elem)
//            List(1, 3, 55)
//            List(3, 55, 66)
//            List(55, 66, 77)
        }

        for (elem <- list.sliding(3, 2)) {
            println(elem)
//            List(1, 3, 55)
//            List(55, 66, 77)
        }

        for (elem <- list.sliding(3, 3)) {
            println(elem)
            // 滑动完成之后,最后一个窗口数量不够也要写出来
//            List(1, 3, 55)
//            List(66, 77)
        }
    }
}

集合计算简单函数

object TestSimpleFunction {

    def main(args: Array[String]): Unit = {
        val list = List(1, 4, 55, 77, -33, -90)
        val list2 = List(("a", 1), ("b", 4), ("c", 55), ("d", 77), ("e", -33), ("f", -90))

        // (1)求和
        var sum = 0
        for (elem <- list) {
            sum += elem
        }
        println(sum)      // 14

        println(list.sum) // 14
        // (2)求乘积
        println(list.product) // 50311800

        // (3)最大值
        println(list.max) // 77
        println(list2.max) // (f,-90) 默认以二元组的第一个位置来比较
        // 取二元组的第二个位置作为比较
        println(list2.maxBy((tuple: (String, Int)) => tuple._2)) // (d,77)
        // 简写
        println(list2.maxBy(_._2)) // (d,77)

        // (4)最小值
        println(list.min) // -90
        println(list2.minBy(_._2)) // (f,-90)

        // (5)排序
        // 5.1 sorted,默认从小到大
        val sortedList1 = list.sorted
        println(sortedList1) // List(-90, -33, 1, 4, 55, 77)

        // 从大到小
        // 这个做了两次操作
        println(list.sorted.reverse) // List(77, 55, 4, 1, -33, -90)
        // 一步到位
        println(list.sorted(Ordering[Int].reverse)) // List(77, 55, 4, 1, -33, -90)

        println(list2.sorted) // List((a,1), (b,4), (c,55), (d,77), (e,-33), (f,-90))

        // 5.2 sortedBy
        println(list2.sortBy(_._2)) // List((f,-90), (e,-33), (a,1), (b,4), (c,55), (d,77))
        println(list2.sortBy(_._2)(Ordering[Int].reverse)) // List((d,77), (c,55), (b,4), (a,1), (e,-33), (f,-90))

        // 5.3 sortWith,两个参数不用换位置则返回true,需要换位置则返回true
        println(list.sortWith((a, b) => { a < b })) // List(-90, -33, 1, 4, 55, 77)
        // 简写
        println(list.sortWith(_ < _))               // List(-90, -33, 1, 4, 55, 77)
    }
}

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

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

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

集合计算高级函数

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

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

(3)扁平化 将集合中所有的集合打散组成一个新的集合

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

(5)分组(group) 按照指定的规则对集合的元素进行分组,分组之后得到的是Map

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

(7)折叠

前五个是map操作,后两个是reduce操作,map操作主要是对集合进行转换,reduce是都集合进行汇总

map操作

object TestHighLevelFunctionMap {

    def main(args: Array[String]): Unit = {
        val list = List(1, 2, 3, 4, 5, 6, 7, 8, 9)

        // 1、过滤
        // 选取偶数
        val evenList = list.filter((elem: Int) => {
            elem % 2 == 0
        })
        println(evenList)  // List(2, 4, 6, 8)
        // 选取奇数
        println(list.filter(_ % 2 == 1)) // List(1, 3, 5, 7, 9)

        // 2、map
        // 把集合中每个数乘与2
        println(list.map(_ * 2)) // List(2, 4, 6, 8, 10, 12, 14, 16, 18)

        // 3、扁平化
        val nestedList: List[List[Int]] = List(List(1, 2, 3), List(4, 5), List(6, 7, 8, 9))

        val flatList = nestedList(0) ::: nestedList(1) ::: nestedList(2)
        println(flatList)  // List(1, 2, 3, 4, 5, 6, 7, 8, 9)

        val flatList2 = nestedList.flatten
        println(flatList2) // List(1, 2, 3, 4, 5, 6, 7, 8, 9)

        // 4、扁平映射
        // 将一组字符串进行分词,并保存成分词的列表
        val strs: List[String] = List("hello word", "hello scala", "hello java", "i study")
        val splitList: List[Array[String]] = strs.map(_.split(" ")) // 分词
        val flattenList = splitList.flatten // 打散扁平化

        println(flattenList)  // List(hello, word, hello, scala, hello, java, i, study)

        val flatmapList = strs.flatMap(_.split(" "))
        println(flatmapList)  // List(hello, word, hello, scala, hello, java, i, study)

        // 5、分组groupBy
        // 分成奇数和偶数组
        val groupMap: Map[Int, List[Int]] = list.groupBy(_ % 2)
        val groupMap2: Map[String, List[Int]] = list.groupBy(data => {if (data % 2 == 0) "偶数" else "奇数"})
        println(groupMap)  // Map(1 -> List(1, 3, 5, 7, 9), 0 -> List(2, 4, 6, 8))
        println(groupMap2) // Map(奇数 -> List(1, 3, 5, 7, 9), 偶数 -> List(2, 4, 6, 8))

        // 给定一组词汇,按照单词的首字母进行分组
        val wordList = List("china", "caocao", "liubei", "sunquan")
        println(wordList.groupBy(_.charAt(0)))  // Map(s -> List(sunquan), l -> List(liubei), c -> List(china, caocao))
    }
}

reduce操作,

object TestHighLevelFunctionReduce {

    def main(args: Array[String]): Unit = {

        val list = List(1, 2, 3, 4)

        // 1、reduce,归约
        println(list.reduce(_ + _))      // 10,默认就是reduceLeft
        println(list.reduceLeft(_ + _))  // 10,从左往右加
        println(list.reduceRight(_ + _)) // 10,从右往左加 1 + (2 + (3 + 4))

        println(list.reduce(_ - _))      // -8
        println(list.reduceLeft(_ - _))  // -8,从左往右减
        println(list.reduceRight(_ - _)) // -2,1 - (2 - (3 - 4))


        // 2、fold 折叠
        println(list.fold(10)(_ + _))      // 20,10 + 1 + 2 + 3 + 4
        println(list.foldLeft(10)(_ - _))  // 0,10 - 1 - 2 - 3 - 4
        println(list.foldRight(10)(_ - _)) // 8,1 - (2 - (3 - (4 - 10)))
    }

}

mergeMap的操作

object TestMergeMap {

    def main(args: Array[String]): Unit = {
        val map1 = Map("a" -> 1, "b" -> 2, "c" -> 3, "e" -> 8)
        val map2 = mutable.Map("a" -> 5, "b" -> 6, "c" -> 7, "d" -> 9)

        val map3 = map1.foldLeft(map2)(
            (mergedMap, kv) => {
                val key = kv._1
                val value = kv._2
                mergedMap(key) = mergedMap.getOrElse(key, 0) + value
                mergedMap
            }
        )

        println(map3) // Map(e -> 8, b -> 8, d -> 9, a -> 6, c -> 10)
    }
}

普通 WordCount 案例

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

分析

在这里插入图片描述

object TestCommonWordCount {

    def main(args: Array[String]): Unit = {
        val stringList = List(
            "hello caocao",
            "hello liubei",
            "hello sunquan",
            "caocao is a shuaige",
            "liubei ye shi shuaige",
            "sunquan de gege shi shuaige",
            "caocao lihai"
        )

        // 1、对字符串进行切分,得到一个打散所有单词的列表
//        val wordList = stringList.map(_.split(" "))
//        val wordList2 = wordList.flatten

        val wordList = stringList.flatMap(_.split(" "))
        println(wordList)
        // List(hello, caocao, hello, liubei, hello, sunquan, caocao, is, a, shuaige, liubei, ye, shi, shuaige, sunquan, de, gege, shi, shuaige, caocao, lihai)

        // 2、相同单词进行分组
        val groupMap = wordList.groupBy(word => word)
        println(groupMap)
        // Map(is -> List(is), lihai -> List(lihai), ye -> List(ye), a -> List(a), de -> List(de), shi -> List(shi, shi), gege -> List(gege), caocao -> List(caocao, caocao, caocao), liubei -> List(liubei, liubei), hello -> List(hello, hello, hello), sunquan -> List(sunquan, sunquan), shuaige -> List(shuaige, shuaige, shuaige))

        // 3、对分组之后的list去长度,得到每个单词的个数
        val countMap = groupMap.map(kv => kv._1 -> kv._2.length)

        // 4、将map转换成list,并排序取前三
        val sortList = countMap.toList.sortWith(_._2 > _._2)
        println(sortList)  // List((caocao,3), (hello,3), (shuaige,3), (shi,2), (liubei,2), (sunquan,2), (is,1), (lihai,1), (ye,1), (a,1), (de,1), (gege,1))

        println(sortList.take(3)) // List((caocao,3), (hello,3), (shuaige,3))
    }
}

复杂WordCount案例

object TestComplexWordCount {

    def main(args: Array[String]): Unit = {
        val stringList = List(
            ("hello caocao", 1),
            ("hello liubei", 2),
            ("hello sunquan", 3),
            ("caocao is a shuaige", 4),
            ("liubei ye shi shuaige", 5),
            ("sunquan de gege shi shuaige", 6),
            ("caocao lihai", 7)
        )

        // 思路一,直接展开为普通版本
        val newStringList = stringList.map(
            kv => {
                (kv._1.trim + " ") * kv._2
            }
        )
        println(newStringList)

        // 接下来操作与普通版本完全相同
        val wordCountList: List[(String, Int)] = newStringList
            .flatMap(_.split(" "))             // 空格分词
            .groupBy(word => word)             // 单词分组
            .map(kv => kv._1 -> kv._2.length)  // 统计每个单词出现的个数
            .toList
            .sortWith(_._2 > _._2)             // 排序
            .take(3)
        println(wordCountList) // List((shuaige,15), (caocao,12), (shi,11))

        // 思路二:直接根据预统计的结果进行计算
        val wordCountList2 = stringList
            // 将字符串打散为单词,并结合对应的个数包装成二元组
            .flatMap(tuple => {
                val strings = tuple._1.split(" ")
                strings.map(word => word -> tuple._2)
            }) // List((hello,1), (caocao,1), (hello,2), (liubei,2), (hello,3), (sunquan,3), (caocao,4), (is,4), (a,4), (shuaige,4), (liubei,5), (ye,5), (shi,5), (shuaige,5), (sunquan,6), (de,6), (gege,6), (shi,6), (shuaige,6), (caocao,7), (lihai,7))
            // 对二元组进行分组
            .groupBy(kv => kv._1) // Map(is -> List((is,4)), lihai -> List((lihai,7)), ye -> List((ye,5)), a -> List((a,4)), de -> List((de,6)), shi -> List((shi,5), (shi,6)), gege -> List((gege,6)), caocao -> List((caocao,1), (caocao,4), (caocao,7)), liubei -> List((liubei,2), (liubei,5)), hello -> List((hello,1), (hello,2), (hello,3)), sunquan -> List((sunquan,3), (sunquan,6)), shuaige -> List((shuaige,4), (shuaige,5), (shuaige,6)))
            // 叠加每个单词预统计的个数
            .map(kv => kv._1 -> kv._2.map(_._2).sum)
            .toList
            .sortWith(_._2 > _._2)             // 排序
            .take(3)
        println(wordCountList2) // List((shuaige,15), (caocao,12), (shi,11))
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值