Scala编程基础5:元组、集合、高阶函数详解

一、元组

object TupleDemo5 {
  def main(args: Array[String]): Unit = {
    /**
     * 元组:固定长度的集合
     * 元组和其他List,Set集合不太一样的地方是,元组的每一个元素数据类型,都可以是不一样的
     */
    //5元组
    val tuple5: (Int, Double, String, Boolean, Char) = Tuple5(1, 3.14, "string", true, 'c')
    println(tuple5)    //(1,3.14,string,true,c)

    //使用“_加位置坐标(_1)”获取元组中的元素
    println(tuple5._2)  //3.14
  }
}

二、集合

集合的分类

不可变集合:

List:有序,元素可重复,不可变,长度是固定的
Set:无序,且元素唯一
Map:元素是键值对格式存储的,键是唯一的

可变集合:

ListBuffer:操作是在原有的集合上进行改变

HashSet::同上

1、List

object JiHeDemo1 {
  def main(args: Array[String]): Unit = {
    //创建一个List集合对象
    val intList: List[Int] = List(33, 22, 33, 44, 55, 66, 33, 77, 99, 11)

    //获取集合长度
    println(intList.size) //10
    println(intList.length) //10

    /**
     * 提供了许多java集合没有的方法
     */

    //通过下标所以获取元素
    println(intList(1))

    //获取第一个元素
    println(intList.head)

    //获取最后一个元素
    println(intList.last)

    //除去第一个元素外,返回一个新集合存储剩下的元素
    val tailList: List[Int] = intList.tail
    println(intList)
    println(tailList) //List(22, 33, 44, 55, 66, 33, 77, 99, 11)

    //使用分隔符拼接集合中的元素
    val str: String = intList.mkString("|")
    println(str)

    //将集合元素反转,返回新的集合存储
    val reverseList: List[Int] = intList.reverse
    println(reverseList) //List(11, 99, 77, 33, 66, 55, 44, 33, 22, 33)

    //从左向右取n个元素,返回一个新的集合存储
    val leftToRight: List[Int] = intList.take(3)
    println(leftToRight) //List(33, 22, 33)

    //从右向左取n个元素,返回一个新的集合存储
    val rightToLeft: List[Int] = intList.takeRight(4)
    println(rightToLeft) //List(33, 77, 99, 11)

    //从第一个元素开始取,直到函数的返回值是false的时候
    //def takeWhile(p: A => Boolean)
    val resList: List[Int] = intList.takeWhile(_ % 3 == 0)
    println(resList) //List(33)

    //去重集合中的元素,返回一个新的集合存储
    val distinctLIst: List[Int] = intList.distinct
    println(distinctLIst) //List(33, 22, 44, 55, 66, 77, 99, 11)

    //针对元素是Int的List,可以使用sun函数求和
    val sumList: Int = intList.sum
    println(sumList) // 473

    //获取集合中元素的最大值和最小值
    println(intList.max)
    println(intList.min)

    //集合的遍历
    //方式1:
    for (e <- intList) {
      println(e)
    }
    //方式2:
    intList.foreach(println)  // 等价于intLIst.foreach(println(_)) 等价于 intLIst.foreach(e=> println(e))

  }
}

2、Set

/**
 * Set集合:元素无需且唯一
 * 除了排序以外,List集合有的函数,Set集合都有
 */
object JiHeDemo3 {
  def main(args: Array[String]): Unit = {
    //创建一个Set集合
    val set1: Set[Int] = Set(11, 22, 33, 44, 55, 11, 22, 33, 44, 55)
    println(set1) //Set(33, 22, 44, 11, 55)
    println(set1.mkString("|")) //33|22|44|11|55

    val set2: Set[Int] = Set(11, 22, 33)
    val set3: Set[Int] = Set(22, 33, 44)
    //交集
    println(set2.&(set3)) //等价于println(set2 & set3)  //Set(22, 33)
    println(set2.intersect(set3)) //等价于println(set2 intersect set3)
    //并集
    println(set2.|(set3)) //Set(11, 22, 33, 44)
    println(set2 | set3)
    //差集
    println(set2.&~(set3)) //Set(11)
    println(set2 &~ set3)


    /**
     * 集合之间的转换:
     * toSet、toList、toMap
     */
    //Set-->LIst
    val list: List[Int] = set1.toList
    println(s"list:${list}")  //List(33, 22, 44, 11, 55)
    //List-->Set
    println(s"set:${list.toSet}")  //Set(33, 22, 44, 11, 55)

    val set4: Set[String] = Set("a", "b", "c")
    // 使用map方法将Set中的每个元素转换为(key, value)对,然后使用toMap方法转换为Map
    val map: Map[String, Boolean] = set4.map((key: String) => (key, true)).toMap

    println(map) //Map(a -> true, b -> true, c -> true)


  }
}

3、Map

import scala.collection.{immutable, mutable}

/**
 * Map:元素是键值对的集合,不可变
 */
object JiHeDemo6 {
  def main(args: Array[String]): Unit = {
    //创建一个Map集合
    val map1: Map[Int, String] = Map((1001, "张三"), (1002, "李四")) //方式1
    val map2: Map[Int, String] = Map(1001 -> "张三", 1002 -> "李四", 1003 -> "王五") //方式2
    println(map1) //Map(1001 -> 张三, 1002 -> 李四)
    println(map2) //Map(1001 -> 张三, 1002 -> 李四, 1003 -> 王五)

    //通过键获取值
    println(map1(1001)) //张三
    //    println(map1(1007))  //找不到会报错:NoSuchElementException

    //通过键获取值,如果找不到返回默认值
    println(map1.getOrElse(1007, "未找到该值")) //未找到该值


    val map3: Map[String, Int] = Map("1001" -> 19, "1002" -> 12, "1003" -> 17, "1004" -> 16)
    //需求:将每一个学生的年龄加1
    val map4: Map[String, Int] = map3.map((kv: (String, Int)) => {
      //这里的每个键值对,在map中被封装成一个2元组(key,value)
      println(kv)
      val key: String = kv._1
      val value: Int = kv._2
      key -> (value + 1) //等价于(key,value+1)
    })
    println(map4) //Map(1001 -> 20, 1002 -> 13, 1003 -> 18, 1004 -> 17)

    //获取Map集合所有的键或所有值
    val keys: Iterable[String] = map4.keys
    println(keys) //Set(1001, 1002, 1003, 1004)
    val values: Iterable[Int] = map4.values
    println(values) //MapLike(20, 13, 18, 17)

    /**
     * 可变的map集合:HashMap
     */
    val hashMap: mutable.HashMap[String, Int] = new mutable.HashMap[String, Int]()

    //使用put添加元素
    hashMap.put("张三", 19)
    hashMap put ("李四", 17)
    hashMap += "王五"->21
    hashMap.+=(("赵六", 18))
    println(hashMap)  //Map(赵六 -> 18, 王五 -> 21, 张三 -> 19, 李四 -> 17)

    //删除元素
    hashMap.-=("赵六")
    hashMap -= "王五"
    println(hashMap)  //Map(张三 -> 19, 李四 -> 17)

  }
}

4、不可变集合ListBuffer与HashSet

import scala.collection.mutable
import scala.collection.mutable.ListBuffer

/**
 * 可变集合
 * 通过观察源码发现,不可变集合属于scala.collection.immutable中
 * 如果我们想要使用可变的集合,就要去scala.collection.mutable下找对应的集合进行使用
 *
 * ListBuffer 操作是在原有的集合上进行改变
 */
object JiHeDemo4 {
  def main(args: Array[String]): Unit = {
    val listBuffer1: ListBuffer[String] = new ListBuffer[String]
    //添加元素
    listBuffer1.append("hao")
    listBuffer1 append "hao"
    listBuffer1.+=("xue")
    listBuffer1 += "xi"
    println(listBuffer1) //ListBuffer(hao, hao, xue, xi)

    //删除元素,从左向右,只会删除第一次出现的对应字符串
    listBuffer1.-=("hao")
    println(listBuffer1) //ListBuffer(hao, xue, xi)
    //同过下标索引删除元素,返回被删除的元素
    val str: String = listBuffer1.remove(1)
    println(str) //xue
    println(listBuffer1) //ListBuffer(hao, xi)

    //批量添加元素
    val listBuffer2: ListBuffer[String] = ListBuffer("aaa", "bbb", "ccc")
    listBuffer1.++=(listBuffer2)
    println(listBuffer1) //ListBuffer(hao, xi, aaa, bbb, ccc)
    println(listBuffer2) //ListBuffer(aaa, bbb, ccc)

    //更新(修改)元素
    listBuffer2.update(2, "ddd")
    println(listBuffer2) //ListBuffer(aaa, bbb, ddd)

    //指定索引位置插入元素
    listBuffer2.insert(2, "ccc")
    println(listBuffer2) //ListBuffer(aaa, bbb, ccc, ddd)


    /**
     * 可变Set集合:HashSet
     * HashSet中的操作与ListBuffer基本一致,在此不作赘述
     *
     */
    val hashSet = new mutable.HashSet[Int]()
    hashSet.+=(11)
    hashSet.+=(22)
    println(hashSet) //Set(22, 11)


  }
}

5、scala集合与java互相转换

import java.util
import scala.collection.JavaConverters.{asScalaBufferConverter, seqAsJavaListConverter}


/**
 * scala中的集合与Java中的集合互相转换
 */
object JiHeDemo10 {
  def main(args: Array[String]): Unit = {
    //创建一个java中的集合
    val arrayList: util.ArrayList[String] = new util.ArrayList[String]()
    arrayList.add("java")
    arrayList.add("python")
    arrayList.add("scala")
    arrayList.add("spark")

    /**
     * java集合-->scala集合
     * 借助隐式转换,调用原本没有的功能
     */
    val list: List[String] = arrayList.asScala.toList
    println(list.sortBy((e:String)=>e))  //List(java, python, scala, spark)

    /**
     * scala集合-->java集合
     */
    val list1: List[Int] = List[Int](11, 22, 33, 44, 55)
    val javaLisrt: util.List[Int] = list1.asJava
    println(javaLisrt)


  }
}

三、高阶函数

          高阶函数:高阶函数(Higher-Order Functions)指的是那些接受函数作为参数或者返回函数作为结果的函数

高阶函数都是操作 Scala 集合的,一般会进行两类操作:转换操作(transformation )和行动操作/聚合操作(actions)。第一种操作类型将集合转换为另一个集合,第二种操作类型返回某些类型的值。

以下是常用的高阶函数:
1、遍历( foreach ):处理集合中每一个元素,直接输出或者其他处理,没有返回值的,不会返回新的集合


2、映射( map ): 处理集合中每一个元素,有返回值的,将处理后的结果使用新的集合存储


3、嵌套的结构展开(flatten):flatten可以把嵌套的结构展开。当有一个集合的集合,然后你想对这些集合的所有元素进行操作时,就会用到 flatten。


4、映射扁平化( flatmap ):flatMap结合了map和flatten的功能。接收一个可以处理嵌套列表的函数,然后把返回结果连接起来。可以把     flatMap,理解为先map,然后再flatten


5、过滤( filter ):过滤出符合条件的元素,有返回值的


6、是否存在( exists )


7、排序( sorted 、 sortBy 、 sortWith )


8、分组( groupBy )


9、聚合计算( reduce )


10、折叠( fold )

object JiHeDemo2 {
  def main(args: Array[String]): Unit = {
    val intList: List[Int] = List(33, 22, 33, 44, 55, 66, 33, 77, 99, 11)

    /**
     * 1、foreach: 处理集合中每一个元素,直接输出或者其他处理,没有返回值的,不会返回新的集合
     */
    //需求:对集合的偶数元素求和
    var sum = 0
    intList.foreach((e: Int) => {
      if (e % 2 == 0) {
        sum += e
      }
    })
    println(f"集合的偶数元素和为${sum}")


    /**
     * 2、map: 处理集合中每一个元素,有返回值,将处理后的结果使用新的集合存储
     */

    //需求:将集合中元素偶数+50,基奇数+100
    val intListMap: List[Int] = intList.map((e: Int) => {
      if (e % 2 == 0) {
        e + 50
      } else {
        e + 100
      }
    })
    println(intList) //List(33, 22, 33, 44, 55, 66, 33, 77, 99, 11)
    println(intListMap) //List(133, 72, 133, 94, 155, 116, 133, 177, 199, 111)


    /**
     * 3、filter:循环集合,将集合中的每一个元素传入到后面的函数中,如果函数的结果为true,
     * 那么这个元素就会被添加到新的集合中,否则不添加
     * 新集合的结果就是过滤后的结果
     */
    //需求:过滤出集合中的偶数元素
    val intLIstFilter: List[Int] = intList.filter((e: Int) => {
      e % 2 == 0
    })
    println(intLIstFilter) //List(22, 44, 66)


    /**
     * 4、flatten:把嵌套的结构展开。当有一个集合的集合,然后你想对这些集合的所有元素进行操作时,就会用到 flatten。
     */
    val arr1: Array[Int] = Array[Int](11, 22, 33)
    val arr2: Array[Int] = Array[Int](44, 55, 66)
    val arrList: List[Array[Int]] = List(arr1, arr2)
    println(arrList.flatten)  //List(11, 22, 33, 44, 55, 66)



    /**
     * 5、flatMap:效果类似于hive中的explode函数
     * flatMap的工作方式是将集合中的每个元素应用一个函数,每个元素经过该函数会返回一个新的集合,
     * 然后将所有这些新集合的元素“扁平化”到一个单一的集合中
     */
    val stringList1: List[String] = List("python|java|scala", "mysql|clickhouse|hbase", "hadoop|hive|zookeeper")
    //需求:将每一个单词切分出来
    //方式一:for循环
    for (words <- stringList1) {
      val stringsArr: Array[String] = words.split("\\|")
      for (word <- stringsArr) {
        println(word)
      }
    }

    println("-" * 100)
    //方式2:flatMap
    val stringList2: List[String] = stringList1.flatMap((words: String) => {
      val stringsLIst: Array[String] = words.split("\\|")
      stringsLIst
    })
    println(stringList2) //List(python, java, scala, mysql, clickhouse, hbase, hadoop, hive, zookeeper)
    println("-" * 100)

    /**
     * 6、sort by:排序
     * 将集合中的每一个元素传入到后面的函数中,以指定的方式进行排序
     */
    val listSort1: List[Int] = intList.sortBy((e: Int) => e) //默认以从小到大的顺序排序
    println(listSort1) //List(11, 22, 33, 33, 33, 44, 55, 66, 77, 99)
    val listSort2: List[Int] = intList.sortBy((e: Int) => -e) //加"-"表示以从大到小的顺序排序
    println(listSort2) //List(99, 77, 66, 55, 44, 33, 33, 33, 22, 11)

    //sortWith:指定排序方式
    val listSort3: List[Int] = intList.sortWith((x: Int, y: Int) => x > y)
    println(listSort3) //List(99, 77, 66, 55, 44, 33, 33, 33, 22, 11)


    /**
     * 7、groupBy: 分组
     * 将集合中的每一个元素传入到后面的函数中,相同的元素为一组,返回的是一个Map集合
     */
    val intListGroupBy: Map[Int, List[Int]] = intList.groupBy((e: Int) => e)
    println(intListGroupBy) //Map(33 -> List(33, 33, 33), 77 -> List(77), 22 -> List(22), 44 -> List(44), 66 -> List(66), 11 -> List(11), 99 -> List(99), 55 -> List(55))
  }
}

四、入门案例练习(单词统计)

import scala.io.{BufferedSource, Source}
 /**
     * 使用scala语言完成单词统计
     */
object worldCountDemo7 {
  def main(args: Array[String]): Unit = {
  
    //方式一:分开调用
    val source: BufferedSource = Source.fromFile("D:\\projects\\IdeaProjects\\bigdata29-maven\\scala\\src\\main\\scala\\com\\shujia\\day01\\data\\she_hui_zhu_yi_new")
    val list: List[String] = source.getLines().toList
    println(list) //List(富强、民主、文明, 富强、民主、文明、和谐, 富强、民主、文明、和谐, 爱国、敬业、友善, 爱国、敬业、诚信、友善, 爱国、敬业、诚信、友善)
    val wordList: List[String] = list.flatMap(e => e.split("、"))
    println(wordList) //List(富强, 民主, 文明, 富强, 民主, 文明, 和谐, 富强, 民主, 文明, 和谐, 爱国, 敬业, 友善, 爱国, 敬业, 诚信, 友善, 爱国, 敬业, 诚信, 友善)
    val mapWord: Map[String, List[String]] = wordList.groupBy(e => e)
    println(mapWord) //Map(诚信 -> List(诚信, 诚信), 富强 -> List(富强, 富强, 富强), 爱国 -> List(爱国, 爱国, 爱国), 敬业 -> List(敬业, 敬业, 敬业), 文明 -> List(文明, 文明, 文明), 友善 -> List(友善, 友善, 友善), 民主 -> List(民主, 民主, 民主), 和谐 -> List(和谐, 和谐))

    val mapCount: Map[String, Int] = mapWord.map((kv: (String, List[String])) => {
      kv._1 -> kv._2.size
      //      s"${kv._1}:${kv._2.size}"
    })
    mapCount.foreach(println)
    
    println("=" * 100)

    //方式二:链式调用
    Source.fromFile("scala/data/she_hui_zhu_yi")
      .getLines()
      .toList
      .flatMap(e => e.split("、"))
      .groupBy(e => e)
      .map((kv: (String, List[String])) => kv._1 -> kv._2.size)
      .foreach(println)
  }
}
  • 14
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值