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方法,可以赋初始值;

               

原文地址:https://www.cnblogs.com/lq13035130506/p/12207112.html