zoukankan      html  css  js  c++  java
  • Spark之scala

    一、什么是scala

    scala 是基于JVMde 编程语言。JAVA是运行在jvm上的编程语言,java 源代码通过jvm被编译成class 文件,然后在os上运行class 文件。scala是运行在jvm 上的编程语言,scala源代码通过jvm被编译成class文件,然后在os上运行class文件。

    二语法:

    1.声明值和变量

    var a =12 // 定义变量 vary

    val  b = 23//  定义常量:value

    2.有趣的语法特性

    在scala的变量声明时,可以不指定类型,由解释器自己判断。
        “superman ”*3    //表示字符串“ superman”反复输出3次
        “superman ”*3    //实际上是字符串“ superman”调用方法*,传入的参数是3

    3.函数:

    函数在声明后,无论是否有“=”,都有返回值。当没有“=”的时候,表示返回值是Unit类型,Unit类型的值是()。当有“=”的时候,返回值是函数体中的最后一行的值。如果返回值类型强制指定为Unit类型,那么返回值必定是()。

    4. 判断:

    /**
     * 判断if
     */
    object Test21 extends App{
        def judge(a:Int) :Int = {
          if(a > 0){
             1    //return相当于函数版的break语句
          }else if(a < 0){
            -1
          }else{
            0
          }
        }
        
        var c = judge(-3)
        println(c)
    }
    5.循环
    /**
     * while 和 for循环
     */
    object Test22 extends App{
        /*while循环*/
    //  while(true){
    //    println("hello")
    //  }
      
      
      /*for循环  scala中的for基本形态*/
    //  for(int i = 0 ; i < 5 ; i++)  //java的for循环
    //  for( i : List)                  //增强for
      
    //  println(1 to 10)   //Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    //  for(i <- 1 to 10 ){  //闭区间
    //    println(i)
    //  }
      
    //  for(i <- 1 until 10 ){  //开区间
    //    println(i)
    //  }
      
    //   for(i <- 1 until 10 reverse){  //倒序  不能使用 10 to 1
    //       println(i)
    //   }
       
      /*高级for循环*/
      //守卫
    //    for(i <- 1 to 10 reverse ; if i % 3 == 0){
    //      println(i)
    //    }
      
    //      for(i <- 1 to (10,3)){   //改变步长
    //      println(i)
    //    }
      
    //  for(i <- 1 to 10 ; j <- 1 to 5){  //双重for循环
    //      println(i + " - " + j)
    //  }
      
    //  //for的推导式
    //  var c = for( i <- 1 to 10 )yield (i * 2)
    //  println(c)

    6.常用的数据结构

    6.1数组

    /**
     * 数组
     */
    object Test31 extends App{
      /*定长数组*/
      //使用new定义数组
    //    var arr1 = new Array[Int](5)
    //    arr1(1) = 2
    ////    println(arr1)
    //    for(i <- arr1){
    //      println(i)
    //    }
      
      //使用Array类进行定义
      var arr2 = Array(1,2,3,4,"hehe")
    //  for( i <- arr2){
    //    println(i)
    //  }
      
    //  println(arr2.min)
    //  println(arr2.max)
    //  println(arr2.sum)
    //  println(arr2.mkString("[",",","]"))   //Arrays.toString(arr)  [1,2,3]
      
      /*变长数组*/
    //  var arrbuf1 = ArrayBuffer(1,2,3,4)
    //  arrbuf1 += 5
    //  arrbuf1 -= 3
    //  arrbuf1 ++= Array(3,4,5)
    //  arrbuf1 --= Array(3,4,5)
    //  arrbuf1.toArray
    //  println(arrbuf1.mkString(","))
      
    //  var arrB = arr2.toBuffer
    //  arrB += 9
    //  println(arrB.mkString(","))
      
      
      //filter 和 map用法
      var arr4 = Array(1,2,3,4,5)
      var arr5 = arr4.filter( _ % 2 == 0 ).map( _ * 2)
      println(arr5.mkString(","))
    }
     
    6.2映射
    **
     * 映射
     */
    object Test32 extends App{
      /*不可变的映射*/
      //(zhangsan,18)键值对称作对偶   用()表示
        var map1 = Map[String,Int](("zhangsan" , 18) ,( "lisi" , 19))
        map1 += ("wangwu" -> 80)
    //    map1("zhangsan") = 12
        map1 += ("zhangsan" -> 20)
    //    println(map1("zhangsan"))
    //    for(i <- map1){
    //      println(i)
    //    }
        
    //    if(map1.contains("zhaoliu"))
    //    println(map1("zhaoliu"))
        
        
        /*可变的映射*/
    //    var mapB = scala.collection.mutable.Map[String,Int]("zhangsan"->20,"lisi"->12)
    //    mapB("zhangsan") = 30
    //    for(i <- mapB){
    //      println(i)
    //    }
        
        
        /*与java的互操作*/
    //    var list = new ArrayList[Int]
    //    list.add(1)
    //    list.add(2)
    //    
    //    for(i <- 0 to list.size() - 1 ){
    //      println(list.get(i))
    //    }
        
        /*map其他遍历方式*/
        
    //    for((k,v) <- map1){  //方式一
    //      println(k + "->" + v)
    //    }
        
        //方式二
        var set1 = map1.keys 
        var set2 = map1.keySet 
        for(i <- set1){
          println(map1(i))
        }
    //    println(set2)
    6.3元祖
     
    /**
     * 元组
     */
    object Test33 extends App{
      
      //元组定义
      //对偶(使用“()”表示)只是元组最简单的形式  使用()表示
        var t = (1,2,3,4)
    //    for(i <- t){   //元组不能使用for遍历
    //      println(i)
    //    }
        
    //    println(t _3)   //元组的下标从1开始
    //    println(t _1)   //元组的下标从1开始
        
        var (first,second,third,forth) = t
    //    var (first,second,third,_) = t
    //    println(second)
        
        var s = "Hello World!"
    //    println(s.partition(_.isUpper))
        
        
        //拉链操作
        var arr1 = Array(1,2,3,4,5,6)
        var arr2 = Array("a","b","c","d","e")
        var arr3 = arr1.zip(arr2)   //
    //    for(i <- arr3){
    //      println(i)
    //    }
        println(arr3.mkString(","))
        var map = arr3.toMap   //map
        for(i <- map){
          println(i)
        }
        

    7.类

    类的定义 : 使用class定义

    类的字段:在类中使用var,val定义字段

    类的方法:scala中,使用var定义字段默认提供setter和geter方法,对应的名称为value_= 和value.

    /**
     * 类的基本内容
     */
    
    class TestClass41{
    //   @BeanProperty var monary = 100
      var monary = 100
       
    //   def show {
    //     println("hello")
    //   }
    }
    
    
    object Test41 extends App{
      
        var a = new TestClass41()  //实例化一个类
        a.monary = 200
        println(a.monary)
    //    println(a.show)
        
        //scala使用var定义字段 默认生成对应的setter和getter方法  对应的名称monary_= 和 monary
        
    //    a setMonary 300
    //    println(a getMonary)
        
        //使用val定义字段的时候  scala不在提供setter方法
        
        //@BeanProperty和private不能同时共用
        
        
    }
     
    /**
     * 类的基本内容2
     */
    class TestClass42{
      private var monary = 0
      
      def setMonary(a:Int){  //自定义setter方法
        if(a > 0)
        this.monary = a
      }
      
      def getMonary = {  //自定义getter方法
        this.monary
      }
      
    }
    
    object Test42 extends App{
        var c = new TestClass42
        c setMonary -1000
        println(c getMonary)
        
    }
    构造器:
    /**
     * 类的构造器
     */
    //class TestClass43(var name:String = "xxx" , var age:Int = 0) {  //主构造器  带参数称为默认值
    //  
    ////  var name:String       //需要初始化
    ////  var age:Int 
    ////  public TestClass43 {}   //java的构造器写法
    //  println("name=" + name)
    //  println("age=" + age)
    //  
    //}
    
    class TestClass43 {  //辅助构造器 
      var name:String = "lisi"      //需要初始化
      var age:Int = 0
      
      def this(name:String ){
        this()        //辅助构造器第一行要调用主构造器
        this.name = name
        println("第一个辅助构造器")
      }
      
      def this(name:String ,age:Int){
        this(name)    //还可以调用其他辅助构造器
        this.name = name
        this.age = age
        println("第二个辅助构造器")
      }
       
      println("name=" + name + " age=" + age)
      
      def show = {
        "name!=" + name + " age!=" + age
      }
    }
    
    
    object Test43 extends App{
        var c = new TestClass43("wangwu",90)
    //    println("name=" + c.name)
    //    println("age=" + c.age)
        
        println(c.show)
        
        
    }
     
     
    8.对象
    定义:Object是一种类型,与class非常相似。
    Object可以提供java中的静态字段、静态方法的功能。
     
    伴生对象
    /**
     * 伴生对象
     */
    
    class TestObject51 {
      private var value = 10
      def display{
        println(TestObject51.value)
      }
      
      def show(a:TestObject51){  //自定义getter方法
        this.value =  TestObject51.value
      }
    }
    
    /*伴生对象*/
    object TestObject51{    //对象使用object定义
      //该对象作为同名类的伴生对象
    //  private[this] var value = 10
      private var value = 10
      
      private def show {
        println("超人")
      }
    }
    
    object Test51 extends App{
      
    //    println(TestObject51.value)  //不能访问对象中的私有字段
    //    println(TestObject51.show)
        
    }
     
     
    apply 方法:
    f(arg1,arg2,**)是函数调用方法,用着非常好用,如果f是类的实例,相当于调用类的apply()方法。
    /**
     * apply方法
     */
    
    object Test52 extends App{
    //    var arr = new Array[Int](5)
        var arr = Array.apply(1,2,3,4)  //构造数组使用的是apply方法
        
        var map = Map.apply[String,Int]("zhangsan"->12)
        
    }
     
    9.高阶函数
    1.函数可以赋给变量值
    首先,在scala中,函数是一等公民
    2.匿名函数:
    函数的形式是(形参列表)=>返回值类型
    var ff = (s: string) => s.toUpperCase
    println(ff)
    /**
     * 高阶函数
     */
    
    object Test61 extends App{
        //函数定义
        def add(a:Int ,b:Int) = {
          a + b
        }
    //    var c = add(1,2)
    //    println(c)
        
        var func1 = add _     //把一个函数的实现传递给另外一个函数 
    //    println(func1(1,2))
        
    //    var func2 = (x :Int) =>  x + 3 //传递一个匿名函数给给一个变量
    //    var func3 = (x :Int) =>  {x + 3} //传递一个匿名函数给给一个变量
    //    var func4 = (x :Int) =>  (x + 3) //传递一个匿名函数给给一个变量
        
    //    for(i <- arr)  
    //    Map[String,Int]("zhangsan" -> 12)
    //    println(func2(3))
        
    //    def func5(a:Int ,f:(Int)=>(Int)) = {
    //      f(a) + 1
    //    }
    //    println(func5(4,(x:Int) => {x + 2}))   //传递一个匿名函数给该函数
        
        //调用函数封装举例
    //    def CPU(a:Int) = {
    //      a * 8
    //    }
    //    def GPU(a:Int) = {
    //      a + 9
    //    }
    //    def compute(men:Int,CPU:(Int)=>(Int),GPU:(Int)=>(Int)) = {
    //      men + CPU(2) + GPU(2) 
    //    }
    //    println(compute(4,CPU,GPU))
        
        def func6(f:(Int)=>(Int)) = {
          f(1)
        }
    //    println(func6(_ + 2))  //简写条件:1.只有一行代码   2.只有一个形参  3.把匿名函数作为形参
    //    println(func6(_ + _))  
        
        //总结“_”  :
    //    1.代表数组每一个元素
    //    2.指的是传递是确切的一个函数 而不是忘记给该函数传递参数
    //    3.元组的元素取值    
        
        //思考题
    //    def func7 (x :Int ,y:Int) = {
    //      (y : Int) => {
    //          x + y
    //        } + 2
    //    }
    //    println(func7(3,4)(2))
        
        //一些有用的函数 map foreach reduceLeft 
    //    (1 to 9).map("*" * _).foreach(println _)
        
        var c = (1 to 3).reduceLeft(_ + _)   //1 + 2 + 3
        println(c) 
        
    }
     
     
    3. 函数作为形参(demo 同上)
    1223

    对于只有一个参数的,可以只写函数体。

    fun3(a=>a+2)

    如果形参只有一个,可以在函数体中使用_代替。

    fun3(_+2)

    函数作为形参的终极版本。

    4.把匿名函数放在函数体内
    图片1
    5.一些有用的高阶函数
    图片2
     
    10.继承:

    抽象类
        1.抽象类不一定有抽象字段,有抽象字段或者抽象方法的类一定是抽象类,只需要添加abstract关键字
        2.有抽象字段一定是是抽象类(scala中字段定义时一定要初始化)
        3.重写字段时实质就是在重写字段的setter/getter方法
       

    覆盖方法
        非抽象类覆盖方法的时候,一定使用override。

    覆盖字段
          抽象字段一定要有类型描述。
          覆盖的时候,一定使用override。

    /**
     * 继承--抽象类
     */
    
    abstract class Person {
      //抽象类不一定有抽象字段或者抽象方法
      //有抽象字段或者抽象方法的类  一定是抽象类
      var name:String  
      val age:Int
      def story:String
    }
    
    //方式一
    //class Student extends Person{  //覆盖字段时实质上是覆盖了字段setter、getter方法
    //  var name:String = "Jeckson"  //var定义的字段只能使用var覆盖,并且var覆盖只能是为实现的字段 
    //  val age:Int = 20        //使用val定义的字段只能使用val覆盖 
    ////  def story = "dance"     //
    //  def story = "dance"     //使用def定义的抽象方法可以使用def覆盖也可以使用val ,当def为无参时函数可以使用val
    //}
    
    //方式二
    //class Student (var name:String = "Jeckson" ,val age:Int = 20 ,val story:String = "dance") extends Person 
    
    
    object Test71 extends App{
    //  var c = new Student
    //  println(c.name)
    //  println(c.age)
    //  println(c.story)
      
      var c = new Person {  //方式三  匿名子类
          var name:String = "Jeckson"  //var定义的字段只能使用var覆盖,并且var覆盖只能是为实现的字段 
          val age:Int = 20        //使用val定义的字段只能使用val覆盖 
          def story = "dance"     //
      }
    }

    匿名子类重写超类

    图片3

    抽象字段和抽象方法

    12

    /**
     * 构造顺序
     */
    class Person1 {
      val age:Int = 10
      var arr:Array[Int] = new Array[Int](age)  //调age字段的getter方法
    }
    
    //class student1 extends Person1{
    //  override lazy val age:Int = 18   //如果覆盖的父类不是抽象类  必须要写override
    //}
    
    class student1 extends { //解决办法③
      override val age:Int = 18   //如果覆盖的父类不是抽象类  必须要写override
    } with Person1
    
    //特质
    /*trait student2 {
      var a:Int = 10
      var b:Int
    }
    trait student3{
      def show = "123"
    }
    class student4 extends student2 with student3{
      var b:Int = 1
    }*/
    
    object Test72 extends App{
        var c = new student1
        println(c.age)
        println(c.arr.length)  
        //输出18 0   解决办法:1.字段前面添加final  2.字段前面添加lazy  3.解决办法③
        //原因:
    //      a.主构造器和class类交织在一起
    //      b.子类中使用了override覆盖超类中的字段,构造子类时超类的字段值会被覆盖
    //      c.student1类作为student1的主构造器,调用了超类的Person1的主构造器
    //      d.首先,构造器将age值设置为10
    //      e.接着代码往下走,为了初始化arr数组,调用了age的getter方法
    //      f.而age字段被重写了,也就是说getter方法被重写了
    //      g.被重写的getter方法还没有被初始化,确切说就是字段age还是对象在被分配空间时所有整型字段的初始值
    //      h.arr数组长度被设置为0
    //      i.子类Student1类构造器执行,age被赋值为18
    }

    10 .模式匹配

    更好的switch case

    12

    object Test73 extends App{
    //    var t = (1,2,3)
    //    var (first,second,third) = t   //模式匹配
    //    println(first)
        
        var s = "++"
          
        var result = s match {
          case "a" => println("超人")
          case "*" =>  1
          case "牛人" => "superman"
          case _ if s.contains("=") => (x:Int) => {x + 1} 
          case _ => 0
        }
        
        println(result)
    }

    仅此献给努力的你我。

     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    使用Eolinker拓展API设计
    如何记录API
    API设计
    【翻译】通过API主导的集成来证明您的业务未来
    从状态库迁移分布系统建设方式
    PostgreSql 查询某个模式下面的所有表
    迁移状态库的地市区县信息
    测开和开发的难度对比
    yum源的三种搭建方式
    Harbor实现容器镜像仓库的管理和运维
  • 原文地址:https://www.cnblogs.com/chaoren399/p/4757782.html
Copyright © 2011-2022 走看看