数据字典之Scala

Scala basic kownlege

Posted by lh on 2019-07-10

数据字典之Scala01

$What is Scala

  • Scalable Language(可扩展的语言)的简写

  • Scala是运行在JVM上的 兼容Java程序,支持和 java进行混编(集成java类库)。

  • util类:common-lang3 …

  • 集成面向对象编程和函数式编程的各种特性

  • 拥有high-leve的API: 对比传统的mapreduce程序,只限于 mapper、 reducer算子,scala

  • 提供更多类型的算子可以使用。

$Scala Spark

  • Hadoop的组成: HDFS(分布式文件系统) YARN(资源调度系统) MR(计算引擎)

  • Spark:计算引擎
    spark代替hadoop是不现实的,最多只是计算引擎的更换。
    Spark Flink Kafka
    VFP????

$Scala REPL

  • 交互式命令行

​ 能够很好地展示scala中的数据类型,e.g res0: Int 名字:数据类型

$Scala + IDEA

  • Eclipse 安装插件
  • IDEA + Maven + Scala
    IDEA默认是不支持Scala,所以需要手工安装一下IDEA的Scala插件
    ​ 1)在线安装 考验RP
    ​ 2)离线安装
  • 2.7.5?
  • idea-scala-arache(快速构建)
    仅保留一个dependency,且将scala.version改成2.11.8
    pom里不需要的dependency,repos… 全删了
    默认的代码全部删了

$Scala编译和执行

  • 分步:scalac ==> class ==> scala
    ​ 先scalac编译成.class文件,
    ​ 在用scala执行.class文件,运行程序
  • 一站式:scala xx.scala (编译加执行,区别于java)

$Scala数据类型

  • 图例![](C:\Users\30588\Pictures\Camera Roll\数据类型.png)
  • Scala是完全面向对象的
    ​ Java:
    ​ 原生数据类型: int double float
    ​ 包装类型:Integer Double Float

    Scala:
    

    ​ Int Double Float(完全面向对象)

  • Scala的自动推导
    ​ 定义/声明
    ​ val|var 名称[:数据类型] = xxoo,不需要定义类型
    ​ val name:String = "pk"
    ​ val name = “pk”

  • 注意:var定义的变量可再赋值,val定义的变量不可以。

  • 数据类型转换

    toInt | asIstanceOf[ ] 问题:可能会有精度丢失

    ​ isInstanceOf

    var a=1 var a=1L

  • 占位符和初始化

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    //用占位符必须指定数据类型
    var name:String = _

    //各类型默认值
    scala> var data:Int = _
    data: Int = 0

    scala> var data:Double = _
    data: Double = 0.0

    scala> var data:String = _
    data: String = null

    scala> var data:Long = _
    data: Long = 0

    scala> var data:Float = _
    data: Float = 0.0

    //应用类型默认也是null
    scala> var data:Array[Int] = _
    data: Array[Int] = null

    //占位符修饰的属性不能是val(不可变的)
    scala> val data:Array[Int] = _
    <console>:11: error: unbound placeholder parameter
    val data:Array[Int] = _

$Scala编程规范

  • Scala 一行代码最后是不需要加;

    ​ 情况一:val index =1

    ​ 情况二:val index =2;var index2=3​

  • 注释
    ​ 开发过程中文档注释是一定要有的
    ​ 类:描述清楚你这个类是做什么的
    ​ 方法:描述这个方法是完成什么功能的,如果有入参的话,每个入参是什么意思,返回值是什么

  • 按照文档,注意代码空行规范,一行代码的限制长度,方法限行行数等。

$Scala方法的定义

def 函数名称(x:Int, y:Int):Int = {

1
2
3
4
5
6
// 函数体/方法体
}
==>
def 函数名([参数名:参数类型],...)[:返回值类型 = ] {

}

注意:

  • 函数()里面的东西:入参,可以有,可以没有,可以有多个,多个之间使用逗号分隔

  • 最后一行作为返回值返回,不需要显式的添加return
    递归除外需要显示指定返回类型

  • 函数可以有返回值 也可以没有返回值 Unit
    存在= 代表有返回值,类型可由方法自动推断
    没有= 代表没有返回值,unit

  • 方法的调用
    ​ 1 to 10 ==> 1.to(10)
    ​ 1.get( ) ==> 1.get 默认参数除外:典型的Spark-default-conf

  • 可变参数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    //可以传入多个参数
    def get(name:Int*):Int={}

    //通常用法
    get(1,2,3)

    //特殊用法:传入数组或集合,针对可变参数
    var array = 1 to 10
    get(array:_*)
  • 指定参数

    1
    2
    3
    4
    5
    6
    7
    8
    //定义方法
    def get(x:Int,y:Int):int = { (x+1)*y}

    //通常调用
    get(4,3) ==> 15

    //特殊调用
    get(y=4,x=3) ==> 16

$Scala数组循环

  • 三种简易数组

​ to 左右都闭合 1 to 10

​ range 左闭右开 rang(初始值,步长,次数) to do == > range(10,-1,5) ==> (10,9,8,7)

​ until 左闭右开 1 until 10

  • 遍历数组
1
2
3
4
5
1.  for(x <- arayy){   }  || for(x <- arayy if x>2 ){   } 
2. for(i <- 0 to array.length-1)
3. for(i <- array) yield i*10yield推导)
4. array.foreach(x => print(x))
5. array.reverse.foreach(x => print(x))[reverse反转数组]
  • 数组求和 1到100

​ 数组遍历累加

​ 利用元组

1
2
3
4
5
6
var (count,sum) = (100,0) 
while(count>0){
sum = sum + count
count = count - 1
}
print(sum)
  • 跳出循环(特殊)
1
2
3
4
5
6
7
8
9
10
flag标志位
var flag = true
var sum = 0
while(falg){
if(sum >10){

flag = false
}
sum++
}

$Scala面向对象

  • 封装

  • 继承

    • 父子关系
      • 重写

        • 1
          2
          3
          4
          5
          6
          7
          8
          //方法重写
          overwrite def toString(){}

          //属性重写
          overwrite val num = 10L (可以重写val的属性)

          //典型类
          MemoryManager
      • Object

      • new 对象

        • 1
          //new 子类对象时,会先执行父类构造器再执行子类构造器(和java类似)
  • 多态

    • 多用于接口,增加接口扩展性

      • Animal ani = new Cat( ) ==> Animal ani = new Dog( )
  • 语法

    • 1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      //和java一致
      class Cat {
      //to do
      }


      //构造器
      //构造器分为两种:主构造器 附属构造器

      //主构造器
      //主构造器的属性不用定义,相当于在开有定义了
      class Dog(val name:String,val age:Int){

      val gender:String = _
      //附属构造器
      //附属构造器的属性需要单独定义
      def this(name:String,age:Int,gender:String){
      //第一行必须调用主构造器
      super(name,age)
      this.gender = gender

      }

      }

      //典型类
      Range
      SparkConf
    • 抽象类和接口

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      abstract class Dog{

      //抽象方法
      abstract def toString()

      //抽象属性 java中不可以
      abstract val num = 10L

      //典型类
      SparkEnv
      }

      //接口
      trait Pig{}

      //多实现和继承
      class Cat extends Pig with Dog

      //典型类
      SparkConf
    • 伴生对象和伴生类

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      //伴生类和伴生对象
      //同名且位于同一个类

      //伴生对象
      object Buffer{

      def apply( ) ={

      println("--------------------- Object apply ---------------------")
      new Buffer()

      }

      //类静态方法
      def getA()={

      println("--------------------- Object getA ---------------------")

      }


      }

      //伴生类
      class Buffer{

      def apply( ) ={

      println("--------------------- class apply ---------------------")
      new Buffer()

      }

      def getA() ={

      println("--------------------- class getA ---------------------")

      }

      }


      //注意:创建对象的两种方法
      Buffer bf = new Bffer( )
      Buffer bf = Bffer( )//默认调用Obejct(静态资源)的apply方法,不是每个类都有。


      //总结
      //1.用对象去调用的调用的都是class的属性
      //2.用类名调用的或类名(),都是调用的Object的属性
      1.Buffer.getA Buffer()
      2.new Buffer.getA

      Buffer.getA()
      new Buffer().getA()
      Buffer()
      new Buffer().apply()

      //结果
      --------------------- Object getA ---------------------
      --------------------- class getA ----------------------
      --------------------- Object apply --------------------
      --------------------- class apply ---------------------
    • 枚举

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      //枚举 extend Enumeration
      object container extends Enumeration{

      val SPRING = Value(1,"春天")
      val SUMMER = Value(2,"夏天")
      val AUTUMN = Value(3,"秋天")
      val WINTER = Value(4,"冬天")

      }

      println(container.values)
      println(container(1))
      println(container.withName("冬天"))

      //结果
      [1, 2, 3, 5, 7, 11, 13, 17, 19]
      container.ValueSet(春天, 夏天, 秋天, 冬天)
      春天
      冬天
    • case class 和 case object - 重点

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
       //caseclass详解:https://www.cnblogs.com/MOBIN/p/5299951.html
      // https://zhuanlan.zhihu.com/p/30321358 注意hashMap的结构+map、set考察hashcode 和equals方法,需要同时重写
      //注意这里的属性默认都是val的
      case class Dog(name:String,age:Int)
      var big = Dog("big",10)
      big.age() = 20
      会报不能再分配的错误

      //case class 特点
      自己实现序列化

      //区别
      case class A () 必须有()
      case object b 不能用()

$Scala数据结构

  • 图例![](C:\Users\30588\Pictures\Camera Roll\Scala集合体系.jpg)

  • mutable 和 immutable

    • 这里的可变和不可变是指集合和数组的长度是否可以改变,不是指内容
  • 常用

  • 感觉边长用于追加数据,定长用于统计结果,每一组数组和集合都有两种形态

    • Array - immutable

      • mkString(“前缀”,“分隔符”,“后缀”)
      • sum()
      • min()
      • max()
      • toBuffer 转换
    • ArrayBuffer - mutable

      • 默认长度16
      • insert(index,*)
      • remote( a ) 和 remote( a ,5)
      • trimEnd( 2 ) 删除尾部的数据
      • += 加变长 和 ++= 加定长
      • toArray 转换
    • List - immutable == > (1,2,3,4)

      • Nil ==> 空集合 ==> list( )

      • :: 头加尾 (1) :: (2) ==> (1,2)

      • 1::Nil ==> list(1)

      • list :+ 2

      • 2 :+ list

      • tail ==> 1

      • head ==> (2,3,4)

        • 用tail和head求sum

        • 1
          2
          3
          4
          5
          6
          7
          8
          9
          //递归
          def sum(num:Int*):Int ={
          //出口
          if(num.length == 0){
          0
          }else{
          num.head + sum( num.tail:_* )
          }
          }
      • toBuffer

    • ListBuffer - mutable

      • += 加变长 和 ++= 加定长
      • -= || --= 对应元素
      • toList 转换
    • Set和Map的可变和不可变

      • 1
        2
        3
        //Set和Map中immutable和mutable靠认为制定,没有各自对应的类 
        val map: mutable.Map[Nothing, Nothing] = mutable.Map()
        val set = mutable.Set[Int](1,2,3)
    • Set

    • Map

      • 排序时,需要将Map转成list
      • map是immutable,长度和内容都不可变
    • Tuple

    • Queue

$Scala高阶特性

  • 函数式编程特性
    • 匿名函数
    • 将函数赋值给变量
    • 函数是一等公民
  • 模式匹配和Option
  • 高阶函数
    • 模式匹配
      • match
      • Option
        • Some
        • None
    • 集合的特性(链式编程)
    • map
    • foreach
    • filter
    • reduce
    • reduceLeft
    • reduceRight
    • fold
    • flatten
    • flatMap
    • groupBy
    • find
    • mapValues
    • sorted
    • sortBy
      • list.sortBy( _.1 ) 正序
      • list.sortBy( -_.1) 倒序
    • 集合的交并补
      • diff
      • intersect
      • union
      • distinct
  • 典型高阶特性
    • 字面值
    • 函数式编程
    • 偏函数
    • 部分应用函数
    • 柯里化
    • 隐式转换