• Spark学习(二)scala语法


    一,变量

    1,基本数据类型

    2,基本运算符

    3,定义变量

    4,复杂变量

     (1)定义数组Array:

    •    声明:val aList=new Array[数据类型type](n):声明存储数据类型为type的n个对象,数组初始化为null
    •    声明:val aList=Array(n1,n2,n3...):声明时,可以不用声明数据类型。
    •    调用:aList(m):调用第m个元素。
    •    声明多维数组:val aList=Array.ofDim[数据类型](a,b):声明行为a,列为b的二维数组
    •    调用多维数组中的元素:aList(a1)(b1):调用数组中行为a1,列为b1的元素

    (2)定义元组Tuple(对多个不同类型的对象的简单封装):

    •      声明: val tStudent=("name1",23,"男",560.00):声明元组类型学生的信息为(姓名,年龄,性别,月开销)
    •      调用:tStudent._1(取出"name1");tStudent._2(取出23);tStudent._3(取出"男")....

    (3)定义容器Collection(导包scala.collection;scala.collection.mutable;scala.collection.immutable)

           scala.collection:封装了可变容器和不可变容器的通用操作的超类(从上到下依次继承都是特质(类似Java的接口),不是具体的容器

            

             foreach方法:遍历当前容器内所有元素

    (4)定义序列Sequence(如上图Seq有两个子序列:IndexedSeq和LinearSeq)有存入数据有先后顺序,可以重复

           LindearSeq:列表和队列可以继承该类

                            List(列表):具体的容器类,列表内的对象必须是同类型,列表内的值不可变(必须导包scala.collection.immutable)

                                              定义:val slPeople=List("张三","李四","王五"......)

                                              头部:head;尾部:tail    获取头部(第一个元素:slPeople.head);获取尾部(除去第一个元素以外的元素:slPeople.tail)

                                              向列表头添加新的元素从而生成新的列表:val  slNewList="赵四"::slPeople(不能给列表的尾添加元素)

                                             

                          Range(队列):是一种特殊的带索引的不可变数字等差序列(range内可以存放任何类型数据)

                                               定义:val irNum=new Range(n1,n2,m):与Python的range函数功能相同,n1(开始量)n2(结束量,取不到)m(步长)

                                                1 to  8  by 1:得到包括8的Range(1,8,1)序列

                                                1 until 8  by 1:得到Range(1,8,1)序列

                                            

           IndexedSeq:Vector和ArrayBuffer可以继承该类

                             Vector(向量):

                                                   定义:val svPeople=Vector("张三","李四","王五"......)

                                                   获取元素svPeople(n):获取第n+1个元素

                                                   向Vector的头添加元素:svPeople1="赵四"+:"钱七"+:svPeople;向Vector的尾添加元素:val svPeople2=svPeople:+"孙八"

                                             

    (5)定义集合Set:存放不重复元素,没有先后顺序,用哈希方法去查找元素(默认为不可变集合)

                        可变集:(导包scala.collection.mutable)

                        不可变集:(导包scala.collection.immutable)

    import scala.util.control.Breaks._;
    import scala.collection;
    import scala.collection._;
    import scala.collection.immutable._;   
    var ssPeople=Set("张三","李四");     //Set("张三","李四")是不可变集,将不可变集赋给可变变量ssPeople
    ssPeople+="王五";                   //将"王五"赋加给变量ssPeople后生成新的不可变集Set("张三","李四","王五")
    import scala.collection.mutable._;    //要定义可变集必须导入这个包
    val ssPeople1=Set("张三","李四");      //Set("张三","李四")是可变集,
    ssPeople1+="王五";

                     

    (6)定义映射Map:一系列键值对的容器,键唯一但值不唯一(默认为不可变映射)

                        可变映射:(导包scala.collection.mutable)

                        不可变映射:(导包scala.collection.immutable)

    import scala.util.control.Breaks._;
    import scala.collection;
    import scala.collection._;
    import scala.collection.immutable._;
    var ssPeople=Map("姓名:"->"张三","年龄:"->16);     //不可变映射
    import scala.collection.mutable._;    //要定义可变集必须导入这个包
    val ssPeople1=Map("姓名:"->"张三","年龄:"->16);     //Set("张三","李四")是可变映射,
    ssPeople1+=("性别"->"男","学号:"->20173522);   //向可变映射中添加多个元素
    ssPeople1("姓名:")="李四";      //更新可变映射中的元素
    ssPeople1("学校:")="石家庄铁道大学";    //向可变映射中添加单个元素
    print("查询姓名");
    var result=if(ssPeople1.contains("姓名:"))  ssPeople1("姓名:")  else  "无法查询姓名"  //当映射中存在键为"姓名:"则将对应的值赋给result,否则将无法查询xx赋给result
    print(s"姓名:$result");

                  

    二,输入,输出

         1,从控制台输入(导包:scala.io.StdIn):

             

          2,输出(默认导包scala.Predef):

              (1)类Java的输出方式: print("姓名:"+name+" 年龄:"+age)或println("姓名:"+name+" 年龄:"+age)

             

              (2)类C的输出方式:printf("姓名:%s 年龄:%s",name,age)

            

             (3)s插值字符串输出法:print(s"姓名:$name 年龄:$age")

            

             (4) f插值字符串输出法(格式化):

            

    三,读写文件(导包java.io.PrintWriter和scala.io.Source)

           1,写入(导包java.io.PrintWriter):向文件test.txt中写入信息:

               

              

           2,读取(导包scala.io.Source):

             

    四,控制结构

         1,for结构:

            用法一:基本结构

                

             用法二:for结构中加条件

                   

             用法三:支持多个生成器,用;隔开 

           

            用法四:将遍历的值付给变量

           

          

       2,异常处理(try......catch.....)

       3,循环控制(不存在break和continue终止循环)

            使用Breaks类(导包scala.util.control)

           当使用breakable方法:

    import scala.util.control.Breaks._;
    var i=0;
    val array=Array(1,3,6,15,9,12,16);
    breakable{      //这个大括号不能换行
        for(i<-array)
        {
            if(i>10) break;   //循环到15直接跳出循环
            print(i+"	");
        }
    }

          

       4,判断值是否存在:contains()

    五,类

        1,定义方法:当有返回值,则返回String,Int,Boolean;无返回值,则返回Unit类型

            

             参数列表中的参数不能用val,var修饰

              参数列表没有时,可以不用()

              (参数列表)可以写成{参数列表};当只有一个参数时,可以用中缀调用法

             

              当方法体只有一条语句,可以省略{}

    import scala.util.control.Breaks._;
    class Conent{      //不能换行
        var value=0;
        def dIncrement(s:Int):Unit={
            value+=s;
        }
        def dCurrent():Int={
            value;
        }
    }
    val conent=new Conent;
    conent.value=5;
    conent.dIncrement(2);
    print(conent.dCurrent);

         2,类似Java的get,set方法:value方法相当于Java的Getxx方法,获取类中的变量的值;value_方法相当于Java的Setxx方法,修改类中变量的值。

    import scala.util.control.Breaks._;
    import scala.io.StdIn;
    class Student{
        private var pvsName="";
        private var pviAge=0;
        def valueName=pvsName;
        def valueName_=(newName:String){
            pvsName=newName;
        }
        def valueAge=pviAge;
        def valueAge_=(newAge:Int){
            if(newAge>0 &&newAge<200){
                  pviAge=newAge;
            }
        }
    }
    val students=new Student;
    printf("请输入姓名:");
    var sname=readLine();
    students.valueName_=(sname);
    printf("请输入年龄:")
    var iage=readInt();
    students.valueAge_=(iage);
    printf("学生姓名:%s 	 学生年龄:%d",students.valueName,students.valueAge);

    六,构造器

          主构造器:scala可以定义带参数的类作为一个主构造器,可以给这个类之间传参,改变参数值,输出参数值

        

         辅助构造器:调用形式:this(参数列表)

        

    import scala.util.control.Breaks._;
    import scala.io.StdIn;
    class Student{
        var sName="";
        var age=0;
        println("这是主构造器;");
        def this(sName:String){                       //第一个辅助构造器
            this();                                        //调用主构造器
            this.sName=sName;
            print(s" 这是第一个辅助构造器;姓名:$sName
    ");
        }
        def this(sName:String,age:Int){           //第二个辅助构造器
            this(sName);                            //调用第一个辅助构造器
            this.age=age;
            print(s" 这是第二个辅助构造器;姓名:$sName 	 年龄:$age
    ");
        }
    }
    var getStudent=new Student("张三");                //执行第一个辅助构造器
    var getStudent=new Student("张三",17);          //执行第二个辅助构造器

    运行结果:

          

     (七)对象

       

     1,单例对象:1,定义,使用object定义;object 对象名{ 内容}

                       2,对象内的所有字段和方法都是静态的,不用对对象的进行实例化。

                       3,分类:伴生对象和孤立对象

         1,伴生对象:当类名和单例对象名一样且定义在一个scala代码文件中,则彼此可以访问对方的成员

            

         2,孤立对象:一个scala代码文件内类名和单例对象名都不相同,则这个单例对象称为孤立对象,

    2,apply方法:不断创建对象,自动调用(工厂方法);例如创建数组时,直接val array=Array(“张三”,"李四"),会自动调用apply方法。

                       当要调用的类中定义了apply方法,则不用手动调用apply方法,程序会自动调用该方法。

                       将面向对象编程(调用方法:对象.方法(参数))和函数式编程(方法(参数))结果一致,都可以使用

                       对象调用可以转换为函数调用;函数调用可以转换为对象调用

             

     例子:使用伴生对象,伴生类和apply方法

    import scala.io.StdIn;
    class Student(name:String,age:Int){
        def Test():Unit={
            print(s"姓名:$name,年龄:$age
    ");
        }
    }
    object Student{
        def apply(name:String,age:Int)=new Student(name,age);    //调用伴生类的构造方法
    }
    object Main{
        def main(args: Array[String]): Unit = {
          println("请输入姓名:");
          var name=readLine();
          println("请输入年龄:");
          var age=readInt();
          var student=Student(name,age);                //调用伴生对象的apply方法
          student.Test();
        }
        
    }

          运行结果:

         

     3,update方法:根据对象名取出对象的参数;要使用对象参数时调用。

     (八)类的继承

             1,抽象类:类的成员没有被实例化,用abstract修饰;

                                 在抽象类中可以定义有方法体,被实现的方法

                                 抽象类中的成员,方法不用abstract修饰;但抽象的变量必须声明类型:val name:String;

            2,继承类:必须加extends关键字;

                               子类只能重载val变量

                               如果父类中的变量已经赋值,子类调用父类变量则要加override,如果父类中的变量没有赋值,子类调用父类变量则可以不加override

           3,option类:抽象类,对象:Some对象(返回不为空时,封装到该对象)和None对象(返回为空时)

                      

             

             

              4,特质:有Java的接口功能,但可以在特质中定义有方法体的方法;关键字:trait

                          特质中定义抽象方法可以不用abstract关键字

                          特质可以继承特质

                         一个类可以混入多个特质,关键字:extends 特质名1  with  特质名2

              5,模式匹配:

                1,类似switch()..case:...:不需要break退出

    var grade=readChar();
    grade match {
        case 'A' =>println("85-100");
        case 'B' =>println("75-84");
        case 'C' =>println("60-74");
        case 'D' =>println("30-59");    
        case _=> println("对不起,你输错了")
    }

                例子:case可以判断数据类型                                                                                        case后可以加入判断

                   

              2,case类:自动重载多个有用对象,自动创建伴生对象(apply方法和unapply方法)。

         6,包:可以嵌套定义。

    (九)函数:

             1,定义:

                         

             2,函数字面量:

                          函数类型和值:

                                

                          类型:                

                          值: 

             3,另一种定义函数方式:函数式变量可以调用,可以赋给其他变量(函数名counter可以省略,匿名函数又称Lambda表达式)

                   当函数中变量只出现一次,可以用_占位

                                 

                                

                                

               4,高阶函数:函数的一个参数为另一个函数

                               

     (十)对容器操作:

              1,遍历操作:foreach方法:容器名.foreach(参数)

                      例子:变量映射:

                  

                  

             2,映射操作:

                    例如:对容器元素进行一对一映射操作;关键操作函数:map(具体操作方法)

                 

                  将得到的三个结果容器拍扁成为一个容器;关键操作函数:flatMap(具体操作方法)

                 

             3,过滤操作:关键操作函数:filter(具体过滤操作)

                    例如:将Map中值含有"三"的键值对留下:

                   

                   

            4,归约操作:关键操作函数:reduce(具体操作)

                   

                     归约函数使用了s插值输出方式

                   

          使用fold方法,可以赋初始值;

                   

  • 相关阅读:
    Git 远程仓库 git remote
    同一台电脑关于多个SSH KEY管理
    dotnet core on Linux 环境搭建及入门demo
    Cannot load JDBC driver class 'com.mysql.jdbc.Driver '
    Mac OS 配置Maven
    Linux中profile、bashrc、bash_profile之间的区别和联系
    如何在Mac的Finder中显示/usr、/tmp、/var等隐藏目录
    Mac OS X 下查看和设置JAVA_HOME
    SSM框架整合(IntelliJ IDEA + maven + Spring + SpringMVC + MyBatis)
    事件
  • 原文地址:https://www.cnblogs.com/lq13035130506/p/12207112.html
Copyright © 2020-2023  润新知