1-scala基础

1、scala

  ①定义:Scala设计的初衷是要集成面向对象编程和函数式编程的各种特性。Scala运行于Java平台(Java虚拟机),并兼容现有的Java程序。

  ②特点:优雅、简洁、一行代码抵得上多行Java代码

2、变量和常量、懒值

   var r = 1
    r = 2;
    r = 'A'                          //这是有问题的,var定义的r是int
  
    var rStr: String = "1"         //可以在定义的时候指定类型
    var a,b = 1                    //定义多个变量

    val c = 2                    //常量   

   注 :val就不能再赋值了。与之对应的,var可以在它生命周期中被多次赋值

   注:官方推荐val 使用val的好处:

    1、更安全         2、代码可读性更高        3、资源回收更快,方法执行完,val所定义的变量即回收

  注:只有val修饰的变量才能被lazy修饰;使用lazy定义变量后,只有在调用该变量时才会实例化这个变量的值。而且惰性变量只能是不可变变量;

3、包装类(富包装器)

    原型       包装类          高级包装       java包装

    byte       Byte         RichByte       Byte


    short        Short          RichShort        Short


    int          Int            RichInt        Integer


    long       Long           RichLong        Long

扫描二维码关注公众号,回复: 5621187 查看本文章


    char        Char         RichChar       Character


    float        Float         RichFloat        Float


    double       Double          RichDouble       Double


    boolean       Boolean        RichBoolean       Boolean

              BigInt                     BigInteger    //存储大的整数

              BigDecimal                  BigDecimal   //存储位数比较多的小数

      使用实例:

     val valchar: char = 'a'
     val valFloat: Float = 1.1F
     val valRichLong: RichLong = 1L

  注:包装类是为了使基本类型转变为类。而高级包装(富包装器)则是在包装类的基础上扩展了很多其他的方法。

4、继承

     

  Any则是AnyVal, AnyRef的父类。也就是说,Any是所有Scala类型的父类,它内置于Scala内部,由编译器实现。

  AnyRef是所有「引用类型」的父(根)类

  AnyVal是所有「值类型」的父(根)类

  Null类型为所有引用类型的子类,其拥有唯一的实例:null。

  Nothing:它是所有类的子类。

5、返回值(Unit、Option)

  Unit类型是一个特殊的值类型,它等价于Java中的void。

  Option:返回some类型具或NONE,由于有这个特性,在返回值中经常用,防止出现异常

  val arr = Array[Int](1,2)
  val value1: Option[String] = arr(1)
  val value2: Option[String] = arr(3)    
 
  println(value1)         // Some("value1")
  println(value2)         // None    

6、表达式

  表达式:一个具有执行结果的代码块,分为条件表达式、块表达式

  val y = if (x > 0 ) 1 else -1        //条件表达式

  val res = {                       //块表达式
    if (x < 0) {
        -1
    } else {
        "error"
    }
  }

7、循环

    ①to、until

        println(1 to 10 )                  //1-10
        println(1 until 10 )                //1-9,不打印最后一个数

    ②基础循环

        for( i <- 1 to 10 ){
                  println(i)
            }

    ③多层循环

        for(i <- 1 to 10; j <- 1 until 10){
                  println("i="+ i +",    j="+j)        //当i=1,j循环1-9;当i=2,j循环1-9
            }

    ④加条件循环

        for(i<- 1 to 10 ;if (i%2) == 0 ;if (i == 4) ){
                  println(i)                //4,当满足是偶数且i==4才输出
        }

    ⑤yield 

        for( i <- 1 to 10 ) yield{
                  i * 2                    //返回乘以2以后的集合
            }

    ⑥跳出循环

        import util.control.Breaks._

        breakable(            
            for(i<-0 until 10) {
                if(i==5){
                    break()            //如果i == 5,就终止breakable包裹的这一堆,此时类似于break
                }
                println(i)
            }
        )

        for(i<-0 until 10) {
            breakable{
                if(i==5){
                    break()           //如果i == 5,就终止breakable包裹的这一堆,此时类似于continue
                }
                println(i)
            }
        }

8、函数

    ①简单函数定义

        def fun (a: Int , b: Int ) : Unit = {
               println(a+b)
         }

    ②递归函数

           def fun(num :Int) :Int= {
                  if(num ==1)
                        num
                  else 
                        num * fun2(num-1)
               }
               print(fun(5))                //求5的阶乘

    ③带默认值的函数

         def fun(a :Int = 10,b:Int) = {
                  println(a+b)
             }
             fun(b=2)

    ④可变参数的函数

        def fun(elements :Int*)={
                  var sum = 0;
                  for(elem <- elements){
                        sum += elem
                  }
                  sum
            }
            println(fun(1,2,3,4))

    ⑤匿名函数

            val value2 = ()=>{
                  println(" ")                //无参数匿名函数
            }

            
            val value3 = (a:Int,b:Int) =>{        
                  a+b                    //有参数的匿名函数
            }

    ⑥偏应用函数

        def log(date :Date, s :String)= {
                  println("date is "+ date +",log is "+ s)
            }

            val date = new Date()

        val logWithDate = log(date,_:String)

        logWithDate("log11")

        //注:偏应用函数是一种表达式,不需要提供函数需要的所有参数,只需要提供部分,或不提供所需参数。

    ⑦生产函数

        def mulBy(factor : Double) = (x : Double) => factor * x 

        val quintuple = mulBy(5)                 //quintuple=(x : Double) => 5* x 

        quintuple(20)                    // 100 

        //注:mulBy输入的是一个double类型,返回的是一个匿名函数

    ⑧函数柯里化

        //将一个函数变为两个函数的顺序调用。比如1+3+4 ,可以分为(1 + 3)+ 4 两个函数

        def add(x:Int,y:Int)=x+y    <==>    def add(x:Int)(y:Int) = x + y        //调用:add(1,2)、add(1)(2)

  注:方法和函数的区别

    ①Scala中使用val语句可以定义函数,def语句定义方法

    ②函数可作为一个参数传入到方法中,而方法不行

    ③方法转函数:val f1 = m _  

9、高阶函数

   定义:以函数作为参数或者返回值的函数

    ①函数作为值

        声明:
            val f: (String, Int) => Char = _ . charAt (_) 
        调用:    
            f("lihaozong",5);    

    ②函数作为参数

        声明:
            def P(f : (Double) =>Double) = f(0 . 25)
        调用:    
            P( ceil._ )                                     // 1 . 0 

        注:函数P的参数是一个函数f(输入、输出都是double),返回值函数f输入为0.25时的输出

10、对象、单例对象、伴生对象 

  单例对象:scala类的一个实例,使用class创建,但是在单例对象中没有静态方法和静态字段

  伴生对象:在Scala的类中,与单例对象类名相同并且用object修饰的对象叫做伴生对象

      ①apply:当object进行初始化时、集合中取值时候(array(5)、list(1,2,3).foreach等)都要用到

      ②unapply(提取器):经常用在模式匹配或者偏函数中

  注:伴生对象类似于java中的工具类,里面封装的静态成员

11、IO

    import scala.io.Source
    val source = Source.fromFile("1.txt", "UTF-8")
    for (line <- source.getLines) print(line)

12、闭包 

  定义:函数引用外部变量叫闭包。之所以要单独提出来,因为在分布式计算中,main方法中定义的全局变量,main中的方法不能直接使用Spark的Task调度器会把方法传给Excutor,但不能传递变量。这也是定义广播变量的原因

13、泛型

  基础的泛型,此处不讲,主要讲的是比java中多出来的概念。

    协变:对类型A和B,A是B的子类型,那么List[A]是List[B]的子类型

        def A(animals: List[Animal]): Unit = {....}
        
        val cats: List[Cat] = List(Cat("Whiskers"), Cat("Tom"))

        A(cats)                        //根据协变List(Cat("Whiskers"), Cat("Tom")为 List[Animal]子类,可以调用


    上界:  T <: A ,表示类型变量 T 必须是 类型 A 子类

        class PetContainer[P <: Pet](p: P) {....}            //输入参数p的类型P必须是类型Pet的子类

    下界: B >: A 表示参数类型或抽象类型  B 须是类型A的父类

        def prepend[U >: B](elem: U): Unit ={...}

    上下文界定:T : M, 其中M 必须为泛型类, 必须存在一个M[T]的隐式值

        class Pair_Context[T : Ordering](val first: T, val second: T){
            def smaller(implicit ord: Ordering[T]) =
            if(ord.compare(first, second) < 0) first else second
        }

猜你喜欢

转载自www.cnblogs.com/lihaozong2013/p/10580859.html