你的位置:首页 > 信息动态 > 新闻中心
信息动态
联系我们

scala——Set、Map、迭代器、扁平化、过滤、排序、分组、聚合

2021-11-30 6:48:29

4、Set集合

Set(也叫: 集)代表没有重复元素的集合。特点是: 唯一, 无序

  • 唯一 的意思是 Set中的元素具有唯一性, 没有重复元素
  • 无序 的意思是 Set集中的元素, 添加顺序和取出顺序不一致
格式一: 创建一个空的不可变集
val/var 变量名 = Set[类型]()
格式二: 给定元素来创建一个不可变集
val/var 变量名 = Set(元素1, 元素2, 元素3...)

示例

//案例: 演示不可变集.
object ClassDemo16 {
    def main(args: Array[String]): Unit = {
        //1. 定义一个空的整型不可变集.
        val set1 = Set[Int]()
        //2. 定义一个不可变集,保存以下元素:1,1,3,2,4,8.
        val set2 = Set(1, 1, 3, 2, 4, 8)
        //3. 打印结果.
        println(s"set1: ${set1}")
        println(s"set2: ${set2}")
    }
}

不可变集的常见操

  • 获取集的大小( size )
  • 遍历集( 和遍历数组一致 )
  • 添加一个元素,生成一个新的Set( + )
  • 拼接两个集,生成一个新的Set( ++ )
  • 拼接集和列表,生成一个新的Set( ++ )
//案例: 演示不可变集的常用操作.
object ClassDemo17 {
  def main(args: Array[String]): Unit = {
    //1. 创建一个集,包含以下元素:1,1,2,3,4,5
    val set1 = Set(1, 1, 2, 3, 4, 5)
    //2. 获取集的大小
    println("set1的长度为: " + set1.size)
    //3. 遍历集,打印每个元素
    println("set1集中的元素为: ")
    for (i <- set1) println(i)
    println("-" * 15)
    //4. 删除元素1,生成新的集
    val set2 = set1 - 1
    println("set2: " + set2)
    //5. 拼接另一个集(6, 7, 8)
    val set3 = set1 ++ Set(6, 7, 8)
    println("set3: " + set3)
    //6. 拼接一个列表(6,7,8, 9)
    val set4 = set1 ++ List(6, 7, 8, 9)
    println("set4: " + set4)
  }
}

可变集

可变集指的是元素, 集的长度都可变, 它的创建方式和不可变集的创建方式一致,只不过需要先导入可变集类。

手动导入: import scala.collection.mutable.Set

import scala.collection.mutable.Set

//案例: 演示可变集.
object ClassDemo18 {
  def main(args: Array[String]): Unit = {
    //1. 定义一个可变集,包含以下元素: 1,2,3, 4
    val set1 = Set(1, 2, 3, 4)
    //2. 添加元素5到可变集中
    set1 += 5
    //3. 添加元素6, 7, 8到可变集中
    //set1 ++= Set(6, 7, 8)
    set1 ++= List(6, 7, 8) //两种写法均可.
    //4. 从可变集中移除元素1
    set1 -= 1
    //5. 从可变集中移除元素3, 5, 7
    //set1 --= Set(3, 5, 7)
    set1 --= List(3, 5, 7) //两种写法均可.
    //6. 打印结果.
    println(set1)
  }
}

映射

映射指的就是Map。它是由键值对(key, value)组成的集合。特点是: 键具有唯一性, 但是值可以重复. 在Scala中, Map也分为不可变Map和可变Map。

不可变Map

不可变Map指的是元素, 长度都不可变

val/var map = Map(键->值, 键->值, 键->值...) // 推荐,可读性更好
val/var map = Map((键, 值), (键, 值), (键, 值), (键, 值)...)

示例

//案例: 演示不可变Map
object ClassDemo19 {
    def main(args: Array[String]): Unit = {
        //1. 定义一个映射,包含以下学生姓名和年龄数据.
        val map1 = Map("张三" -> 23, "李四" -> 24, "李四" -> 40)
        val map2 = Map(("张三", 23),("李四", 24), ("李四" -> 40))
        //2. 打印结果.
        println(s"map1: ${map1}")
        println(s"map2: ${map2}")
    }
}

可变Map

可变Map指的是元素, 长度都可变. 定义语法与不可变Map一致,

只不过需要先手动导包: import scala.collection.mutable.Map

示例

import scala.collection.mutable.Map
//案例: 演示可变Map.
object ClassDemo20 {
    def main(args: Array[String]): Unit = {
        //1. 定义一个映射,包含以下学生姓名和年龄数据.
        val map1 = Map("张三" -> 23, "李四" -> 24)
        val map2 = Map(("张三", 23),("李四", 24))
        //2. 修改张三的年龄为30
        map1("张三") = 30
        //3. 打印结果
        println(s"map1: ${map1}")
        println(s"map2: ${map2}")
    }
}

Map基本操作

  • map(key) : 根据键获取其对应的值, 键不存在返回None.

  • map.keys : 获取所有的键.

  • map.values : 获取所有的值.

  • 遍历map集合: 可以通过普通for实现.

  • getOrElse: 根据键获取其对应的值, 如果键不存在, 则返回指定的默认值

  • +号 : 增加键值对, 并生成一个新的Map.

注意: 如果是可变Map, 则可以通过 +=或者++= 直接往该可变Map中添加键值对元素
  • -号 : 根据键删除其对应的键值对元素, 并生成一个新的Map.

    注意: 如果是可变Map, 则可以通过 -=或者--= 直接从该可变Map中删除键值对元素.
    

示例

import scala.collection.mutable.Map

//案例: 演示Map的常见操作.
object ClassDemo21 {
  def main(args: Array[String]): Unit = {
    //1. 定义一个映射,包含以下学生姓名和年龄数据: 张三 -> 23, 李四 -> 24
    val map1 = Map("张三" -> 23, "李四" -> 24)
    //2. 获取张三的年龄, 并打印.
    println(map1.get("张三"))
    //3. 获取所有的学生姓名, 并打印.
    println(map1.keys)
    //4. 获取所有的学生年龄, 并打印.
    println(map1.values)
    //5. 打印所有的学生姓名和年龄.
    for ((k, v) <- map1) println(s"键:${k}, 值:${v}")
    println("-" * 15)
    //6. 获取`王五`的年龄,如果`王五`不存在,则返回-1, 并打印.
    println(map1.getOrElse("王五", -1))
    println("-" * 15)
    //7. 新增一个学生:王五, 25, 并打印结果.
    /*//不可变Map
    val map2 = map1 + ("王五" -> 25)
    println(s"map1: ${map1}")
    println(s"map2: ${map2}")*/
    map1 += ("王五" -> 25)
    //8. 将`李四`从可变映射中移除, 并打印.
    map1 -= "李四"
    println(s"map1: ${map1}")
  }
}

迭代器(iterator)

Scala针对每一类集合都提供了一个迭代器(iterator), 用来迭代访问集合.

迭代器中有两个方法:

  • hasNext方法: 查询容器中是否有下一个元素
  • next方法: 返回迭代器的下一个元素,如果没有,抛出NoSuchElementException

示例

//案例: 演示迭代器
object ClassDemo22 {
  def main(args: Array[String]): Unit = {
    //1. 定义一个列表,包含以下元素:1,2,3,4,5
    val list1 = List(1, 2, 3, 4, 5)
    //2. 使用while循环和迭代器,遍历打印该列表.
    //2.1 根据列表获取其对应的迭代器对象.
    val it = list1.iterator
    //2.2 判断迭代器中是否有下一个元素.
    while(it.hasNext){
      //2.3 如果有, 则获取下一个元素, 并打印.
      println(it.next)
    }
    //分割线.
    println("-" * 15)
    //迭代完后, 再次使用该迭代器获取元素, 则抛异常: NoSuchElementException
    println(it.next)
  }
}


函数式编程

在这里插入图片描述

遍历(foreach)

def foreach(f:(A) => Unit): Unit
//简写形式
def foreach(函数)

示例

//案例: 演示foreach函数
object ClassDemo23 {
    def main(args: Array[String]): Unit = {
        //1. 定义一个列表, 包含1, 2, 3, 4
        val list1 = List(1, 2, 3, 4)
        //2. 通过foreach函数遍历上述的列表.
        //x:表示集合中的每个元素 函数体表示输出集合中的每个元素.
        list1.foreach((x:Int) => println(x))
    }
}
//案例: 演示简化函数定义.
object ClassDemo24 {
    def main(args: Array[String]): Unit = {
        //1. 有一个列表,包含元素1,2,3,4,请使用foreach方法遍历打印每个元素.
        val list1 = List(1, 2, 3, 4)
        list1.foreach((x:Int) => println(x))
        println("-" * 15)
        //2. 使用类型推断来简化函数定义.
        list1.foreach(x => println(x))
        println("-" * 15)
        //3. 使用下划线来简化函数定义
        list1.foreach(println(_))
    }
}

映射(map)

def map[B](f: (A) ⇒ B): TraversableOnce[B]
//简写形式:
def map(函数对象)

示例

//案例: 演示map函数(映射)
object ClassDemo25 {
    def main(args: Array[String]): Unit = {
        //1. 创建一个列表,包含元素1,2,3,4
        val list1 = List(1, 2, 3, 4)
        //2. 将上述的数字转换成对应个数的`*`, 即: 1变为*, 2变为**, 以此类推.
        //方式一: 普通写法
        val list2 = list1.map((x:Int) => "*" * x)
        println(s"list2: ${list2}")
        //方式二: 通过类型推断实现.
        val list3 = list1.map(x => "*" * x)
        println(s"list3: ${list3}")
        //方式三: 通过下划线实现.
        val list4 = list1.map("*" * _)
        println(s"list4: ${list4}")
    }
}

扁平化映射(flatMap)

扁平化映射可以理解为先map,然后再flatten

def flatMap[B](f:(A) => GenTraversableOnce[B]): TraversableOnce[B]
//简写形式:
def flatMap(f:(A) => 要将元素A转换成的集合B的列表)

需求

  1. 有一个包含了若干个文本行的列表:“hadoop hive spark flink flume”, “kudu hbase sqoop storm”
  2. 获取到文本行中的每一个单词,并将每一个单词都放到列表中.

示例

//案例: 演示映射扁平化(flatMap)
object ClassDemo26 {
  def main(args: Array[String]): Unit = {
    //1. 有一个包含了若干个文本行的列表:"hadoop hive spark flink flume", "kudu hbase sqoop storm"
      val list1 = List("hadoop hive spark flink flume", "kudu hbase sqoop storm")
      //2. 获取到文本行中的每一个单词,并将每一个单词都放到列表中.
      //方式一: 通过map, flatten实现.
      val list2 = list1.map(_.split(" "))
      val list3 = list2.flatten
      println(s"list3: ${list3}")
    //方式二: 通过flatMap实现.
    val list4 = list1.flatMap(_.split(" "))
    println(s"list4: ${list4}")
  }
}

过滤(filter)

过滤指的是 过滤出(筛选出)符合一定条件的元素 .

def filter(f:(A) => Boolean): TraversableOnce[A]
//简写形式:
def filter(f:(A) => 筛选条件)

示例

//案例: 演示过滤(filter)
object ClassDemo27 {
    def main(args: Array[String]): Unit = {
        //1. 有一个数字列表,元素为:1,2,3,4,5,6,7,8,9
        val list1 = (1 to 9).toList
        //2. 请过滤出所有的偶数
        val list2 = list1.filter(_ % 2 == 0)
        println(s"list2: ${list2}")
    }
}

排序

sorted 用来对集合元素进行默认排序 ,对列表元素按照升序进行排列 . 如果需要降序排列, 则升序后, 再通过 reverse 实现

sortBy 用来对集合按照指定字段排序

sortWith 用来对集合进行自定义排序

示例

//案例: 演示默认排序(sorted)
object ClassDemo28 {
    def main(args: Array[String]): Unit = {
        //1. 定义一个列表,包含以下元素: 3, 1, 2, 9, 7
        val list1 = List(3, 1, 2, 9, 7)
        //2. 对列表进行升序排序
        val list2 = list1.sorted
        println(s"list2: ${list2}")
        //3. 对列表进行降序排列.
        val list3 = list2.reverse
        println(s"list3: ${list3}")
    }
}

//案例: 演示根据指定字段排序(sortBy)
object ClassDemo29 {
    def main(args: Array[String]): Unit = {
        //1. 有一个列表,分别包含几下文本行:"01 hadoop", "02 flume", "03 hive", "04 spark"
        val list1 = List("01 hadoop", "02 flume", "03 hive", "04 spark")
        //2. 请按照单词字母进行排序
        //val list2 = list1.sortBy(x => x.split(" ")(1))
        //简写形式:
        val list2 = list1.sortBy(_.split(" ")(1))
        println(s"list2: ${list2}")
    }
}
//案例: 演示自定义排序(sortWith)
object ClassDemo30 {
    def main(args: Array[String]): Unit = {
        //1. 有一个列表,包含以下元素:2,3,1,6,4,5
        val list1 = List(2,3,1,6,4,5)
        //2. 使用sortWith对列表进行降序排序
        //val list2 = list1.sortWith((x, y)=> x > y) //降序
        //简写形式:
        val list2 = list1.sortWith(_ > _) //降序
        println(s"list2: ${list2}")
    }
}		

分组(groupBy)

分组指的是 将数据按照指定条件进行分组 , 从而方便我们对数据进行统计分析.
在这里插入图片描述

//案例: 演示分组函数(groupBy)
object ClassDemo31 {
  def main(args: Array[String]): Unit = {
    //1. 有一个列表,包含了学生的姓名和性别: "刘德华" -> "男", "刘亦菲" -> "女", "胡歌" -> "男"
    val list1 = List("刘德华" -> "男", "刘亦菲" -> "女", "胡歌" -> "男")
    //2. 请按照性别进行分组.
    //val list2 = list1.groupBy(x => x._2)
    //简写形式
    val list2 = list1.groupBy(_._2)
    //println(s"list2: ${list2}")
    //3. 统计不同性别的学生人数.
    val list3 = list2.map(x => x._1 -> x._2.size)
    println(s"list3: ${list3}")
  }
}

聚合操作

所谓的聚合操作指的是 将一个列表中的数据合并为一个 . 这种操作经常用来统计分析中. 常用的聚合操作主要有两个:

  • reduce: 用来对集合元素进行聚合计算

    reduce和reduceLeft效果一致,表示从左到右计算
    reduceRight表示从右到左计算
    
  • fold: 用来对集合元素进行折叠计算

fold与reduce很像,只不过多了一个指定初始值参数.

示例

object ClassDemo32 {
def main(args: Array[String]): Unit = {
        //1. 定义一个列表,包含以下元素:1,2,3,4,5,6,7,8,9,10
        val list1 = (1 to 10).toList
        //2. 使用reduce计算所有元素的和
        //val list2 = list1.reduce((x, y) => x + y)
        //简写形式:
        val list2 = list1.reduce(_ + _)
        val list3 = list1.reduceLeft(_ + _)
        val list4 = list1.reduceRight(_ + _)
        println(s"list2: ${list2}")
        println(s"list3: ${list3}")
        println(s"list4: ${list4}")
    }
}
//案例: 演示折叠计算(fold)
object ClassDemo33 {
    def main(args: Array[String]): Unit = {
        //1. 定义一个列表,包含以下元素:1,2,3,4,5,6,7,8,9,10
        val list1 = (1 to 10).toList
        //2. 假设初始化值是100, 使用fold计算所有元素的和
        //val list2 = list1.fold(100)((x, y) => x + y)
        //简写形式:
        val list2 = list1.fold(100)(_ + _)
        val list3 = list1.foldLeft(100)(_ + _)
        val list4 = list1.foldRight(100)(_ + _)
        println(s"list2: ${list2}")
        println(s"list3: ${list3}")
        println(s"list4: ${list4}")
    }
}