Scala语言

Scala简介

Scala和java一样 , 是基于JVM的语言 . Scala是面向对象+面向函数编程的语言 .

Scala的特性:

1 . 与java无缝整合 , Scala也是编译成.class文件 , 交给JVM执行的. 所以java可以和Scala互相调用 .
2 . 类型推断机制 , Scala的变量类型是var , 常量类型是val . Scala常用val , 因为JVM的垃圾回收机制可以很好的回收. 所谓类型推断即对于数字字符等类型可以自动推导判断 …
3 . 支持并发和分布式 , Scala语言的通讯模型Actor设计的时候支持多台服务器节点单进程多线程执行任务 .
4 . 特质特性 , Scala既可以使用变量也可以使用常量 , 即支持单继承, 也支持多继承 , 同时也支持单实现和多实现 .
5 . 模式匹配 , Scala的Switch不止可以匹配值, 还可以匹配类型 .
6 . 高阶函数 , 不止是值可以作为参数进行传递 , 方法也可以作为参数被传递 .

Scala语法

数据类型
  • val , var(声明, 底层类型如下)
    类型字节数bit数取值范围
    Byte1字节1*8-128-127
    Short22*8-32769 - 32767
    Int44*8-2147483648 - 2147483647
    Long88*8-9223372036854775808 - 9223372036854775807
    Float44*8单精度浮点数
    Doule88*8双精度浮点数
    Char字母1字节,中文2字节英文字母:1 * 8,汉字:2 * 8Unicode字符,范围U+0000 - U+FFFF
    String取决于字符长度取决于字符长度字符串
    Boolean11*8布尔类型
    (以上类型声明val,var的时候自动推导,不可像java一样声明)
  • Unit表示没有返回值 , 相当于java中的void
  • Null表示空值,空引用
  • Nothing 所有其他类型的子类型,表示没有值 . 其存在的价值在于自动推导的时候如果无法推导就会返回Nothing .
  • Any 在Scala语言中所有类型的父类和超类 , 任何实例都属于Any类型 . 但Any类型不等同于Object , 因为Any类型继承自Object类 .
  • AnyRef 所有引用类型的超类 .
  • AnyVal 所有值类型的超类 . 在这里插入图片描述
scala基本语法
package com.credi

/**
  * class是类 , object是对象
  * scala中定义的object中的变量,方法都是静态的
  * scala语句结束后不必像java一定要以";"结尾, 可写可不写,系统会自动在每一行的结尾补,多行代码写一行的时候一定要写
  * class名称和object名称可以相同 , 同名的class是object的伴生类 , 同名的object是class的伴生对象 , 伴生类和伴生对象之间可以互相访问私有变量
  * 同一个包下class名称不能和class相同 , object同理
  */
// object不可以传参 , class可以
object Lesson_ObjAndClass {  //object中的变量和方法都是静态的! 相当于java中的单例对象
//object person{                //object名称和class名称可以相同 , 同名的class是object的伴生类 , 同名的object是class的伴生对象 , 伴生类和伴生对象之间可以互相访问私有变量

  val slogan = "today is good day"   //静态属性

  def main(args: Array[String]): Unit = {   //main方法,程序入口,静态的
    //变量
    var a = 100      //赋值
//    var a: Int = 100 //变量名后跟隐藏类型可强行指定变量类型
    a = 10           //重新赋值
    print(a+"---------->");        //打印后不换行
    //常量
    val b = "今天风儿好喧嚣"
//    b = "呵呵"        //常量赋值后不可更改
    println(b)       //打印后换行

    //创建静态对象
    val person = new person("张星彩",18)
    println(person.name)                 //class类不用像java写get,set  
    person.show()                         //调用show方法
//      println(person.gender)                //伴生类和伴生对象之间可以互相访问私有变量

    //to操作符
    println(1 to 10) //1,2,3....10
    println(1 until 10) //1,2,3...9
    println(1 to (10,2))//1,3,5,7,9
    println(1 until (9,2))//1,3,5,7

    //循环控制语句
    // 1 .if
    val i = 10
    if(i<10){
      println("小于10")
    }else if(i>=10 && i<=20){
      println(i);
    }else{
      println("哈哈..")
    }

    // 2 . for
    for(j<- 1 to 10){ //循环输出1-10 不用声明
      print(j + "==>");
      for(k<- 20 to 30){ //嵌套循环
        print(k+" ");
      }
      println()
    }
    println("--------------")
    // 2 . 2 for嵌套简化
    for(j <- 1 to 10 ; k <- 20 to 30){ // 每遍历一次j的值 , 把k的值全部遍历一次
      println("j = " + j + "  k = " + k)
    }

    // 2 . 3 99乘法表
    for(i <- 1 to 9){
      for(j <- 1 to i){
        print(i+" * "+j+" = "+(i*j)+"    ")
      }
      println()
    }

    // 2 . 4 for和if的综合使用  , i被2整除并且=98
    for(i <- 1 to 100 if(i%2==0) if(i==98)){
      println(i)
    }

    // 2 . 5 for循环遍历的结果放到集合中
    val result = for(i <- 1 to 10 if(i%10==0)) yield i //yield关键字把符合结果的i值依次放到result集合中
    println(result)
    // foreach循环遍历
    result.foreach(x=>{  //将result集合的每个元素依次赋给x
      println(x)          //每遍历一个元素,把x的值输出
    })
    // foreach简化, 如果result只有1个元素 , 可以简化如下
    result.foreach(println)
  }

}

//class Person{                     //class 是scala中的类
class person(xname:String,xage:Int) { //scala的类可以传参 , 不用写构造函数了???
  val name = xname
  val age = xage
  var addr: String = null
  private var gender = "girl"

  println("类中的println方法");       //new 一个class的时候,除了普通的函数不执行,其他的都会被执行

  //def:定义方法的开头关键字
  def this(xname: String, xage: Int, xaddr: String) { //构造函数重载 
    this(xname,xage)                                  //这样调用是必须的
    this.addr = xaddr
  }

  def show()={                                        //普通函数声明
    println("hello scala" +"====" + Lesson_ObjAndClass.slogan)//调用了class类的静态属性
  }
}
函数
package com.credi

import java.util.Date

/**
  * Created by Administrator on 2019/2/6.
  */
object Lesson_fun {
  def main(args: Array[String]): Unit = {

    println(fun(5));println()   //调用递归函数
    println("不给参数:"+fun()+"---给参数:"+fun(1,5)+"---只给一个参数:"+fun(b=100))  //调用带默认值的函数
    fun("a","b","c");println()  //调用可变参数的函数
    fun2('晴','朗')              //调用匿名函数

    //5 . 偏应用函数
    //5.1场景
    def showTime(d:Date , log:Char): Unit ={
      println("date is " +d+" log is "+log)
    }
    val date = new Date();

    //5.2针对问题 : 以下步骤麻烦
    showTime(date,'a')
    showTime(date,'b')
    showTime(date,'c')

    //5.3偏应用函数 , 优化
    val fun3 =  showTime(date:Date, _: Char) // _类似占位符
    fun3('e')
    fun3('d')
    fun3('f')

    //6 . 调用高阶函数
      fun6("高阶函数",funTest)                // 函数作为参数 , 传函数名即可 , 函数参数值在高阶函数方法块内传递

    //6.2 调用高阶函数 , 参数为匿名函数
    fun6("高阶函数 ,参数为匿名函数 :" , (i:Int,j:Int)=>{i*j})

    //6.3 调用高阶函数 , 返回值为函数
    println(fun62("a","b")(1,2))              // 猜测下执行过程

    // 7 . 柯里化函数
    fun7(1,2)(3)                               //柯里化函数就是高阶函数的简化版 , 看上去是否与6.3相似
  }

  //1 . 递归函数
  def fun(num:Int) :Int /*递归要显示声明返回类型*/= {
    if(num==1){
      1          //符合条件返回1
    }else{
      print(num)
      fun(num-1)  //否则调用自己
    }
  }

  //2 . 有默认值的函数
  def fun(a:Int=2 , b:Int=3):Int ={
    a*b
  }

  //3 . 可变参数和匿名函数
  def fun(elems:String*) ={ //*代表可传多个参数 , 将多个参数放入elems集合
    // 3.1for循环遍历elems集合
//    for(e<-elems){
//      print(e)
//    }
    // 3.2foreach和匿名函数遍历集合
    elems.foreach(s=>{ print(s) })  //foreach遍历每个元素, 值赋予s , '=>{}'匿名函数
    elems.foreach(print)          //可以简化
  }

  //4 . 匿名函数, 没有方法名的方法
  val fun2 = (a:Char, b:Char)=>{   //将2含2个形参的匿名参数赋值给常量fun
    println(a+"->"+b)
  }

  //6 . 高阶函数
  /*
   * 函数的参数和返回值都可以是函数
   */
  def funTest(i: Int,j:Int):Int = {
    (i+j)/100
  }
  def fun6(s:String,f:(Int,Int)=>Int): String ={   //定义参数的时候,定义所传函数的形参和返回值类型
    val result = f(100,100) //funTest的参数在这里传
    println(s+"-->"+result)
    s+"-->"+result          //返回值
  }

  //6 . 2 函数的返回是函数
  def fun62(s:String,s2:String):(Int,Int)=>Int ={   //:(Int,Int)=>Int  返回函数的参数和返回值类型
    def test(i:Int,j:Int):Int ={
      i+j
    }
    test
  }

  //7 柯里化函数
  def fun7(a:Int,b:Int)(c:Int):Int={
    println(a+b+c)
    a+b+c
  }
}


String字符串,数组容器元组,Trait
package com.credi

import java.io.{BufferedInputStream, FileInputStream, OutputStream}

/**
  * Created by Administrator on 2019/2/6.
  */
object Lesson_StrAndArr {
  def main(args: Array[String]): Unit = {
    // 1 . String字符串
    //String
    val s = "credi"
    val s1 = "Credi"
    println(s.equals(s1))           //false
    println(s.equalsIgnoreCase(s1)) //true

    //StringBuilder
    val builder  = new StringBuilder
    builder.+('a')                  //追长字符
    builder.++=("bc")               //追长字符串
    builder.append(true)            //追加类型
    println(builder)

    // 2 . 数组容器
    //Array 数组
    val arr = Array(1,2,3,"4",true)     //数组类型 Any
    val arr2 = Array[Int](1,2,3,4,5)    //Int
    val arr3 = new Array[String](3)     //String  ,  长度为3
    arr3(2) = "三"                       // 单个元素赋值
    arr.foreach(print)                  //简单遍历
    for(a<-arr3){                       //循环遍历
      println(a)
    }

    //List集合 , 有序可重复
    val list = List(1,2,3,4,5)
    list.foreach(print)

      // map方法
    val list2 = List[String]("hello yesterday","hello today","hello tomorrow")
    val result:List[Array[String]] = list2.map(s=>{s.split(" ")})        //将list2三个字符串元素依次按空格切分 ,形成三个数组
    //{"hello yesterday","hello today","hello tomorrow"} --> {[hello , yesterday] , [hello , today] , [hello , tomorrow]}
    for(s<-result){
      println(s(0))
      println(s(1))
    }
      //flatMap方法
    val result2 = list2.flatMap(s=>{s.split(" ")})                      //将list2的三个元素按空格直接切成6个字符串
    result2.foreach(s=>{
      print(s+" ")
    })
    println("----------------------------------")
       //filter
    val result3 = list2.filter(s=>{         //filter :过滤 ,接受的参数是boolean , s = false的元素被过滤掉
      !s.equals("hello yesterday")          //s 等于 "hello yesterday" 返回false , 会被过滤掉
    })
    result3.foreach(println)

    //Set 无序不可重复
    val set = Set[Int](1,2,2,3,4,5)
    set.foreach(println)

    //Map
    val map = Map(1->'a' ,(2,'b') , 1->'c')     // 1,2是key  , b,c是value , key重复会被覆盖
    map.foreach(println)    // (1,a)会被覆盖
    val value = map.get(2)                      // get方法根据key返回Option , Some代表有值, None代表无值
    println(value)
    val value2 = map.get(2).get                 // 在后面再加.get就可以拿到具体的值 , 但是key不存在会报NoSuchElementException
    println(value2)
    val value3 = map.get(20).getOrElse("xxxx")  // 或者加.getOrElse(String) , 如果key不存在 , 会把String参数返回 , 不报异常
    println(value3)
    //遍历map的key
    val keys: Iterable[Int] = map.keys
    for(k<-keys){
      print(k+" ")
    }; println()
    //遍历所有的value
    val values: Iterable[Char] = map.values
    values.foreach(print);println()

    // Tuple 元祖 ,scala新增的
    val tuple2 = new Tuple2(1,'a')      //new 可以省略  , 其实map的每个key,value元素相当于2元祖
    println(tuple2.swap)      //只有Tuple2有swap方法  , 作用是两个元素调换前后位置
    val tuple22 = Tuple22(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,22)   //Tuple22最多支持32个
    println(tuple22._22)      //tuple有toString方法 , ._1-22
    val tuple = (1,'g',"b")                 //Tuple也可以省略

    // 遍历Tuple , 和集合数组的遍历不同
    val ite: Iterator[Any] = tuple.productIterator
    while(ite.hasNext){
      println(ite.next())
    }

    //Trait
    val p = new Person("a",17)
    val p2 = new Person("a",18)
    p.read("p")
    p.listen("p")
    println(p.isEqual(p2))
    println(p.isNotEqual(p2))
  }

  //4 Trait 类似java抽象类,接口
  /*
   * Trait 不可以传参 ,支持 多继承(extends ... with ... with ...) 多实现
   */
  trait Read{
    def read(name:String): Unit ={
      println(name+" is read ....")
    }

    //抽象方法
    def isEqual(p:Any):Boolean
    def isNotEqual(p:Any): Boolean ={
      isEqual(p)
    }
  }
  trait Listen{
    def listen(name:String): Unit ={
      println(name + " is listen .....")
    }
  }

  class Person(xname:String,xage:Int) extends Read with Listen{  //多继承

    //成员属性
    val name = xname
    val age = xage

    def isEqual(p: Any): Boolean ={
      //判断两个Person对象的name是否相等
      p.isInstanceOf[Person]/*p是不是Person类的对象*/ && p.asInstanceOf[Person]/*将p类型转换为Person*/.name.equals(this.name)
    }
  }

}

模糊匹配 ,样例类 , Actor通信
  • Actor通信,需要向编码器导入jar包:scala-actors.jar
package com.credi

import scala.actors.Actor

/**
  * Created by Administrator on 2019/2/6.
  */
object Lesson_Match {


  def main(args: Array[String]): Unit = {

    //模糊匹配
    val tuple = (1,"hello",'a',1.1,true)
    val iter = tuple.productIterator
    while(iter.hasNext){
      val one = iter.next()   //遍历tuple元组的每个元素
      MatchMethod(one)
    }

    //样例类
    val m1 = new Man("星彩",18)
    val m2 = new Man("星彩",18)
    println(m1.equals(m2))       //和java一样 , 如果不是样例类, 对象是不会相等的 , 不同对象在堆空间占不同的内存 , 有不同的地址索引

    //两台Actor相互通信
    val actor1 = new MyActor1()
    val actor2 = new MyActor2(actor1)
    actor1.start()                 //启动通信模型
    actor2.start()
    //actor ! "hello"               //发送消息
  }

  def MatchMethod(o: Any) = {
    //1 . 模糊匹配 ,不仅可以匹配值 , 还可以匹配类型  , 匹配的顺序是自上而下匹配 , 匹配成功跳出当次循环
    //值得注意的是 ,在匹配过程中会发生值的类型自动转换
    o match {
      case 1 => println("匹配值 , value=1")
      case i:String => println("匹配类型 , 元素的类型的String...") //如果元素的类型是String , 执行方法块 , 元素别名是i
      case i:Double => {  println("double类型:"+i) }
      case _ => println("default...")   //模糊匹配 , 什么都匹配不到就输出default...
    }
  }
}

//2 . 样例类 , 关键词case , 相当于java中重写了equals,hashcode,copy和toString方法的类
case class Man(xname:String,xage:Int){
  val name = xname
  val age = xage
}

/**
  3 . Actor通信模型 , Spark底层节点之间的通信使用的是Akka通信模型 , Akka就是Actor实现的.
  Actor相当于我们理解的Thread线程
  Actor解决了线程之间锁的问题
*/
class MyActor1 extends Actor{

  override def act(): Unit = { //act方法, 接到消息后的处理

    while(true){
      receive{  //接受消息
        case m:Messge => {
          if(m.msg.equals("hello1")){
            println("收到actor2的消息:"+m.msg)
            m.actor ! Messge(this,"hello2")  //向2发送消息
          }
        }
        case _=>{ println("default ....")}
      }
    }
  }
}
class MyActor2(actor1:Actor) extends Actor{

  actor1 ! Messge(this,"hello1")   //自动向actor1发送消息(messge对象) class类对象创建时 ,除一般函数不执行, 其他都执行

  override def act(): Unit = { //act方法, 接到消息后的处理
    while(true){
      receive{  //接受消息
        case m:Messge => {
          if(m.msg.equals("hello2")){
            println("收到actor1的消息:"+m.msg)
            m.actor ! Messge(this,"hello1")   //向1发送消息
          }
        }
        case _=>{ println("default ....")}
      }
    }
  }
}

//为了让1,2实现相互通信的样例类
case class Messge(actor: Actor,msg:String)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值