大数据——Scala 元组

Scala

元组(Tuple)

  1. 元组(Tuple)本身是一个用于存储1到多个元素的容器,需要注意的是,元组不是集合!!!Scala中所有的集合都在scala.collection包,Tuple是scala包下,但是集合操作中很多时候需要使用到元组

  2. 如果元素类型一致且元素有序可重复,可以使用序列(Seq);如果元素类型一致且元素无序不可重复,可以使用集合(Set);如果元素是键值对形式,可以使用映射(Map);如果元素类型不一致,那么使用元组Tuple

  3. 需要注意的是,Scala中提供了Tuple1~Tuple22,即元组中最多能够存储22个元素

  4. 之前学习的Map中存储的就是Tuple2,即Map(tuple2, tuple2, ...)。Tuple2又称之为对偶元组

  5. 元组定义格式

    scala 复制代码
    package com.fe.tuple
    
    object TupleDemo {
    
      def main(args: Array[String]): Unit = {
    
        // 定义格式
        // 方式一
        // 声明了Tuple3,元组定义好之后不可变
        // 推荐使用这种方式
        val t1: (String, Int, Char) = ("Bob", 15, 'm')
        println(t1)
        // 方式二
        // val t2: Tuple4[String, Int, Double, Double] = Tuple4[String, Int, Double, Double]("Amy", 18, 165, 58)
        // val t2: Tuple4[String, Int, Double, Double] = Tuple4("Amy", 18, 165, 58)
        val t2: Tuple4[String, Int, Double, Double] = ("Amy", 18, 165, 58)
        println(t2)
        // 方式三
        // 元组支持拆分
        // val t3 = ("Sam", 15, "male")
        // 如果要获取元组中的元素,通过   _顺序   的形式来获取
        // val mame = t3._1
        // val age = t3._2
        // val gender = t3._3
        // val (name, age, gender) = t3
        // 简化
        val (name, age, gender) = ("Sam", 15, "male")
        println(name)
        println(age)
        println(gender)
    
        val (r1, r2, r3) = randTo100()
        println(r1)
        println(r2)
        println(r3)
    
      }
    
      def randTo100(): (Int, Int, Int) = {
        val r1 = (Math.random() * 100).toInt
        val r2 = (Math.random() * 100).toInt
        val r3 = (Math.random() * 100).toInt
        (r1, r2, r3)
      }
    
    }
  6. 遍历元组

    scala 复制代码
    package com.fe.tuple
    
    object TupleDemo2 {
    
      def main(args: Array[String]): Unit = {
    
        // 遍历元组
        val t = ("Bob", 10, "male", 4, 6, 152.2, 50.3, "北京")
        // 产生迭代器 - 将元组中的所有的元素放入Iterator中返回
        val it: Iterator[Any] = t.productIterator
        // while(it.hasNext) println(it.next())
        // for (elem <- it) println(elem)
        it.foreach(println)
        // 根据元素类型来进行后续不同的操作
        /*
        for (e <- it) {
          if(e.isInstanceOf[String]){
            val str = e.asInstanceOf[String]
            // 可以针对字符串进行后续操作
          } else if(e.isInstanceOf[Int]){
            val i = e.asInstanceOf[Int]
          }
        }
         */
    
      }
    
    }
  7. 元组也可以形成嵌套

    scala 复制代码
    // 元组嵌套
    val t3 = (("Bob", 15), ("Amy", "female", 14), "Alex", (3, 5, "David"))
    println(t3)
    println(t3._1._1)

集合

转换

  1. 操作一

    scala 复制代码
    package com.fe.collection
    
    object CollectionDemo {
    
      def main(args: Array[String]): Unit = {
    
        // 数组 -> 其他
        val arr = Array[Int](2, 3, 4, 2, 8, 8, 9)
        val arrToList = arr.toList
        println(arrToList)
        val arrToSet = arr.toSet
        println(arrToSet)
    
        // 列表 -> 其他
        val list = List[Int](2, 3, 1, 4, 3, 2, 6)
        val listToArray = list.toArray
        println(listToArray.mkString(", "))
        val listToSet = list.toSet
        println(listToSet)
    
        // 集合 -> 其他
        val set = Set[Int](1, 2, 3, 4, 5)
        val setToArray = set.toArray
        println(setToArray.mkString(", "))
        val setToList = set.toList
        println(setToList)
    
      }
    
    }
  2. 操作二

    scala 复制代码
    package com.fe.collection
    
    object CollectionDemo2 {
    
      def main(args: Array[String]): Unit = {
    
        val map = Map[String, Int]("Bob" -> 15, "Bruce" -> 16, "Bally" -> 17, "Cindy" -> 19, "Canto" -> 16)
        // Map -> Array
        val mapToArray = map.toArray
        println(mapToArray.mkString("\t"))
        // Map -> List
        val mapToList = map.toList
        println(mapToList)
        // Map -> Set
        val mapToSet = map.toSet
        println(mapToSet)
    
        // Array/List/Set如果需要转化为Map,要求其中的元素必须是对偶元组
        val list = List[(Int, Int)]((1, 1), (2, 4), (3, 6))
        println(list(1)._1)
        val listToMap = list.toMap
        println(listToMap)
    
      }
    
    }

常用函数

  1. 衍生子集合

    scala 复制代码
    package com.fe.collection
    
    object FunctionDemo {
    
      def main(args: Array[String]): Unit = {
    
        val list = List[Int](2, 1, 4, 7, 8, 5, 6)
        val set = Set[Int](2, 1, 4, 7, 8, 5, 6)
    
        // 获取第一个元素
        println(list.head)
        println(set.head)
        // 获取最后一个元素
        println(list.last)
        println(set.last)
        // 去除第一个元素以外的其他元素构成的子集合
        println(list.tail)
        println(set.tail)
        // 去除最后一个元素以外的其他元素构成的子集合
        println(list.init)
        println(set.init)
        // 翻转列表
        println(list.reverse)
        // 从头部开始,向后获取指定个数的元素,构成子集合返回
        println(list.take(3))
        println(set.take(3))
        // 从尾部开始,向前获取指定个数的元素,构成子集合返回
        println(list.takeRight(3))
        println(set.takeRight(3))
        // 从头部开始,向后删除指定个数的元素,将剩余元素构成子集合返回
        println(list.drop(3))
        println(set.drop(3))
        // 从尾部开始,向前删除指定个数的元素,将剩余元素构成子集合返回
        println(list.dropRight(3))
        println(set.dropRight(3))
        // 从头开始,获取满足条件的元素,直到碰到不满足条件的元素结束,获取到的元素作为子集合返回
        println(list.takeWhile(_ < 5))
        // 从头开始,删除满足条件的元素,直到碰到不满足条件的元素结束,剩余的元素作为子集合返回
        println(list.dropWhile(_ < 5))
    
      }
    
    }
  2. 衍生集合

    scala 复制代码
    package com.fe.collection
    
    object FunctionDemo2 {
    
      def main(args: Array[String]): Unit = {
    
        val number = List[Int](1, 2, 3, 4, 5, 6, 7)
        val square = List[Int](1, 4, 9, 16, 25, 36, 49)
        // 拉链
        // 将两个list合并成一个list,并且能够将元素来一一对应
        // (1,1), (2,4), (3,9) ...
        // 拉链实际上是将对应位置上的元素合并成一个元组之后,放入一个list中返回
        // 如果两个列表元素个数不一样,那么以短的长度来计算
        // Seq、Set、Map也可以进行拉链操作!!!
        val zipList: List[(Int, Int)] = number.zip(square)
        println(zipList)
        // 需要将两个list合并成一个Map
        val zipMap = number.zip(square).toMap
        println(zipMap)
    
        val list = List[Int](2, 6, 4, 8, 7, 9, 1)
        val set = Set[Int](2, 6, 4, 8, 7, 9, 1)
        // 切分子集合
        // 从指定下标开始,将列表切分为2个子列表,放入一个Tuple中返回
        // val subLists:Tuple2[List[Int], List[Int]] = list.splitAt(4)
        val subLists: (List[Int], List[Int]) = list.splitAt(4)
        println(subLists)
        println(subLists._1(1))
        val subSets: (Set[Int], Set[Int]) = set.splitAt(4)
        println(subSets)
        // 从集合的集合指定的起始下标开始,切到指定下标结束,不包含指定下标
        println(list.slice(1, 4))
        println(set.slice(1, 4))
        // 滑动函数 - 将集合中固定个数元素进行组合,构成一个新的迭代器
        // 0,1,2  1,2,3  2,3,4 ...
        list.sliding(3).foreach(println)
        set.sliding(3).foreach(println)
        // 指定步长的华东
        // 0,1,2   2,3,4  4,5,6 ...
        list.sliding(3, 2).foreach(println)
        set.sliding(3, 2).foreach(println)
    
      }
    
    }
  3. reducefold操作

    scala 复制代码
    package com.fe.collection
    
    object FunctionDemo3 {
    
      def main(args: Array[String]): Unit = {
    
        val list = List[Int](1, 2, 3, 4, 5, 6, 7, 8, 9)
        // reduce:规约。将集合中的元素按照指定逻辑进行计算
        // 需求:获取集合中所有的元素和
        /*
        var sum = 0
        for (e <- list) sum += e
        println(sum)
         */
        // 求和:从左到右依次加上每一个元素
        // 先计算前两个元素的和,获取结果,然后结果在加上第三个元素,再获取结果,加上下一个元素
        // 集合中有5个元素e1~e5
        // e1+e2 -> + e3 -> + e4 -> e5
        // val sum = list.reduce((x, y) => x + y)
        val sum = list.reduce(_ + _)
        println(sum)
        // 需求:获取集合中所有的元素的积
        println(list.reduce(_ * _))
        // 等价于
        println(list.reduceLeft(_ * _))
        // 假设集合中有5个元素:e1~e5
        // e4 - e5 -> r => e3 - r -> r => e2 - r -> r => e1 - r
        println(list.reduceRight(_ - _))
        // fold的操作和reduce操作类似,fold可以指定初始值,在这个初始值的基础上来运算
        // reduce就是没有初始值的fold操作
        println(list.fold(10)(_ + _))
        // 等价
        println(list.foldLeft(10)(_ + _))
        // 从右开始计算的
        println(list.foldRight(10)(_ - _))
        
        // 对集合元素进行集体运算的时候,如果没有初始值,就使用reduce;如果有初始值就使用fold
    
      }
    
    }
  4. 计算函数

    scala 复制代码
    package com.fe.collection
    
    object FunctionDemo4 {
    
      def main(args: Array[String]): Unit = {
    
        val list = List[Int](6, 4, 1, 5, 8, 9, 1, 3, 4)
        // 求和
        // val sum = list.reduce(_ + _)
        val sum = list.sum
        println(sum)
        // 求积
        // val product = list.reduce(_ * _)
        val product = list.product
        println(product)
        // 最大值
        println(list.max)
        // 最小值
        println(list.min)
    
        // 映射:记录的每一个字符出现的次数
        // 需求:出现的最大次数对应的字符
        val characters = List[(Char, Int)]('a' -> 5, 'c' -> 3, 'd' -> 6, 'e' -> 10, 'f' -> 7, 'i' -> 12, 'm' -> 8)
        // 如果集合中存储的是元组,那么默认按照元组的第一个元素来计算大小
        // println(characters.max)
        println(characters.maxBy(t => t._2))
        println(characters.maxBy(_._2))
        // 获取出现次数最少的字符
        println(characters.minBy(_._2))
        // 按照字符的出现次数进行降序排序
        println(characters.sortBy(_._2).reverse)
    
      }
    
    }
  5. 功能函数

    scala 复制代码
    package com.fe.collection
    
    object FunctionDemo5 {
    
      def main(args: Array[String]): Unit = {
    
        val names = List("Amy", "Bob", "Alex", "Hack", "David", "Peter", "Alice", "Bruce", "Henry", "Bill", "Bally")
        // filter:过滤
        // 获取B开头的所有元素
        // val filter = names.filter(n => n.startsWith("B"))
        val filter = names.filter(_.startsWith("B"))
        println(filter)
        // map:映射,将元素按照指定规则,转化为指定形式
        // 将所有的元素转化为大写
        // val map = names.map(e => e.toUpperCase)
        val map = names.map(_.toUpperCase)
        println(map)
        // groupBy:分组,按照指定规则,将元素分为分组
        // 按照首字母,将元素分组
        // val groupBy = names.groupBy(_.charAt(0))
        // println("Amy"(0))
        val groupBy: Map[Char, List[String]] = names.groupBy(_(0))
        println(groupBy)
        // 需求:统计每一个字母开头有多少个名字
        // 先分组,就是上面的分组操作
        // 将映射由(Char -> List)转化为(Char -> Int)形式
        val count = groupBy.map(t => (t._1, t._2.size))
        println(count)
        // flatten:扁平化。将嵌套的所有的集合中的数据提取出来,形成一个大的集合
        val list = List(List(1, 2, 3), List(4, 5), Set(6, 7, 8, 9))
        println(list.flatten)
        // 将列表中的每一个单词拆分出来,形成新的列表
        // String => List[String]
        val words = List("hello amy", "hadoop file system", "local system", "hi bob")
        // println(words.map(_.split(" ")).flatten)
        println(words.flatMap(_.split(" ")))
    
      }
    
    }

其他

泛型

  1. Scala中,通过[]来定义泛型
  2. 不同于Java的地方在于,Scala中的泛型,分为协变、逆变和不变三种形式
    1. 协变:[+T]。A继承了B,那么认为List[A]也继承了List[B]
    2. 逆变:[-T]。A继承了B,那么认为List[B]继承了List[A]
    3. 不变:[T]。A继承了B,List[A]和List[B]之间没有关联
  3. Scala同样存在泛型的上限和下限
    1. [A <: B]:泛型的上限为B
    2. [A >: B]:泛型的下限为B
相关推荐
Themberfue20 分钟前
Java 网络原理 ①-IO多路复用 || 自定义协议 || XML || JSON
xml·java·开发语言·网络·计算机网络·json
m0_6996595621 分钟前
DAY3 QT简易登陆界面优化
开发语言·qt·命令模式
励志成为大佬的小杨1 小时前
关键字初级学习
c语言·开发语言·算法
szpc16212 小时前
100V宽压输入反激隔离电源,适用于N道沟MOSFET或GaN或5V栅极驱动器,无需光耦合
c语言·开发语言·人工智能·单片机·嵌入式硬件·生成对抗网络·fpga开发
m0_748234712 小时前
Java-33 深入浅出 Spring - FactoryBean 和 BeanFactory BeanPostProcessor
java·开发语言·spring
985小水博一枚呀2 小时前
【深度学习基础之多尺度特征提取】特征金字塔(Feature Pyramid)是如何在深度学习网络中提取多尺度特征的?附代码
大数据·网络·人工智能·深度学习·神经网络·cnn
知初~2 小时前
java相关学习文档或网站整理
java·开发语言·学习
我走过的路你也许在走2 小时前
python装饰器学习案例
开发语言·python·学习
我的运维人生2 小时前
Python在数据处理与分析中的高效应用:以金融数据为例
开发语言·python·金融·运维开发·技术共享