Scala基于JVM的编程语言

文章目录

    • 一、Scala简介
        • Scala六个特征:
    • 二、Scala基础
      • 1、数据类型:
      • 2、变量和常量的声明
      • 3、类和对象
        • 伴生类:
        • 伴生对象:
    • 4、if else判断体
    • 5、循环体
        • for循环
        • while循环
        • do while循环
    • 6、函数
        • 1.普通函数(有参函数、无参函数)
        • 2.递归函数:在函数体内调用自己本身
        • 3.默认值的函数
        • 4.可变参数个数的函数
        • 5.匿名函数
        • 6.嵌套函数
        • 7.偏应用函数
        • 8.高阶函数
        • 9. 柯里化函数
    • 7、集合
        • 1.Array
        • 2.List
        • 3.Set
        • 4.Map
        • 5.Tuple
    • 8、字符串
    • 9、Trait特性
    • 10、模式匹配
    • 11、样例类
    • 12、Actor

一、Scala简介

Scala是将面向对象面向函数式整合在一起,基于JVM的编程语言。它由Martin Odersk于2001开发,2004年开始运行在JVM与.Net平台之上,由于其简洁、优雅、类型安全的编程模式而受到关注。

Scala六个特征:

  1. Java和scala可以无缝混编(因为都是基于JVM的编程语言)
  2. 类型推测(自动推测类型)
  3. 并发和分布式(Actor)
  4. 特质trait,特征(整合java中接口和抽象类的优点)
  5. 模式匹配(类似于java中的switch)
  6. 高阶函数(函数的参数是参数,函数的返回是函数)

二、Scala基础

1、数据类型:

Byte、Short、Int、Long、Float、Double、Char、String、Boolean。这些跟JAVA中等同。

  • Unit:表示无值,和java中的void等同
  • Null:空值或空引用
  • Nothing:其他类型的子类,表示没有值
  • Any:所有类型的超类,任何实例都属于Any类型,类似于JAVA中的Object
  • AnyRef:所有引用类型的超类
  • AnyVal:所有值类型的超类
    Scala基于JVM的编程语言_第1张图片

2、变量和常量的声明

变量:用var定义,可修改
常量:用val定义,不可修改
当参数没有修饰,那么外部无法通过对象来调用,类似于JAVA中的private。

var name = "zhangsan"
    val gender = "男"

3、类和对象

伴生类:

class Person{
  val name = "zhangsan"
  val age = 18
  def sayName() = {
    "my name is "+ name
  }
}

伴生对象:

object Lesson_Class {
   def main(args: Array[String]): Unit = {
    val person = new Person()
    println(person.age);
    println(person.sayName())
  }
}

总结:

  1. 构造函数和JAVA不一样,直接类名后加参数
  2. 伴生类中主要声明动态属性,伴生对象主要声明静态属性

4、if else判断体

  • if else
  • if else if else

5、循环体

for循环

  1. 通过索引
  2. 增强for循环
  3. 双重循环
  4. 带有判断条件
  5. yield

while循环

do while循环

总结:

  1. yied关键词能够将符合要求的元素自动封装到一个集合中
  2. 1 to 10包括10,1 until 10不包括10
  3. scala中不能使用count++,只能使用count = count+1
  4. 在scala中没有break跳出循环,可设置标记,例如var flag = true

6、函数

1.普通函数(有参函数、无参函数)

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

2.递归函数:在函数体内调用自己本身

// 计算num的阶乘
def fun1(num:Int):Int = {
    if(num == 1||num == 0) 1
    else num * fun1(num - 1)
}

3.默认值的函数

 def fun2(num1:Int = 10,num2:Int = 20) = {
    num1 + num2
}
  
  def fun3(num1:Int,num2:Int = 20) = {
    num1 + num2
}
  
  def fun4(num1:Int=10,num2:Int) = {
    num1 + num2
}

4.可变参数个数的函数

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

5.匿名函数

var fun6 = (num1:Int,num2:Int) => num1+ num2

6.嵌套函数

 def fun7(num:Int)={
      def fun8(a:Int,b:Int):Int={
        if(a == 1){
          b
        }else{
          fun8(a-1,a*b)
        }
      }
      fun8(num,1)
}

7.偏应用函数

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

  def log(date:Date,content:String) = {
    println("date:" + date + "\tcontent:" + content)
  }
  
  val date = new Date()
  log(date,"log1")
  log(date,"log2")
  log(date,"log3")
  println("==============================")
    
  val logBoundDate = log(date,_:String)
  logBoundDate("log11")
  logBoundDate("log12")
  logBoundDate("log13")

8.高阶函数

函数的参数是函数,或者函数的返回类型是函数,或者函数的参数和函数的返回类型都是函数的函数。

  /**
   * 函数的参数是函数:
   * f1:(Int)=>Int  告诉要传入的函数的格式 
   * 把函数当成了对象穿来穿去、scala支持面向函数编程
   */
  def highFun1(f1:(Int)=>Int,num:Int) = {
    f1(num)
  }
  
  def tmpFun(num1:Int) = {
    num1+1000
  }
  
  /**
   * 函数的返回是函数
   * 函数无参数
   * 函数的返回个(Int,Int)=>Double格式的函数
   */
  def highFun2():(Int,Int)=>Double = {
    def tmpFun2(num1:Int,num2:Int):Double = {
      num1 + num2
    }
    tmpFun2
  }
  
  def highFun3():(Int,Int)=>Double = {
    (num1:Int,num2:Int)=>num1+num2
  }
  
   /**
    * 函数是参数是函数,返回也是函数
    * 这个函数也是高阶函数
    */
  def highFun4(f1:(Int,Int) => Int,num1:Int):(Int)=>Double = {
    val rest = f1(num1,1000)
    (num:Int) => num + 1
  }
  
  def highFun5(num:Int):(Int)=>Int = {
    def fun(a:Int)={
      num + a
    }
    fun
  }

9. 柯里化函数

可理解为对高阶函数的简化

def klhFun(a:Int)(b:Int) = a*b

Scala语言的简写规则:

  1. 函数的返回值类型可以省略,因为scala具备自动推测的功能,他会根据返回值的自动来决定这个函数的返回值类型
  2. 将你要返回的值放在函数的最后一行,那么这个值就会被自动返回
  3. 如果你的函数体内只有一个语句,可以将这行语句与函数名在一行。

总结:

  1. 对于递归函数 必须明确返回值类型,不然不知所措;
  2. 默认值的函数中,如果传入的参数个数与函数定义相同,则传入的数值会覆盖默认值;如果不想覆盖默认值,传入的参数个数小于定义的函数的参数,则需要指定参数名称;
  3. 在scala中+=前后的数值类型必须一致,+前后的数值类型可以不一致;
  4. 注意点:
    1)匿名函数不能显示的声明返回值类型
    2)匿名函数必须赋给一个变量、变量,通过变量来调用这个匿名函数
    3)匿名函数的参数与函数体必须要用=>来关联

7、集合

1.Array

   /**
     * 创建数组的两种方式:
     * 1.new Array[String](3)
     * 2.直接Array
     */   
    //创建类型为Int 长度为3的数组
    val arr1 = new Array[Int](3)
    //创建String 类型的数组,直接赋值
    val arr2 = Array[String]("s100","s200","s300")
    //赋值
    arr1(0) = 100
    arr1(1) = 200
    arr1(2) = 300
   /**
     * 创建二维数组 
     */
    val secArray = new Array[Array[String]](10)
    for(index <- 0 until secArray.length){
      secArray(index) = new Array[String](10)
    }
    
   /**
     * 遍历数组的两种方式
     */
    for(i <- arr1){
    	  println(i)
    }
    arr1.foreach(i => {
      println(i)
    })
    
    for(s <- arr2){
      println(s)
    }
    arr2.foreach { 
      x => println(x) 
    }

2.List

    //创建List 不可变List
    val list = List(1,2,3,4,5)
    
    //遍历List
    list.foreach { x => println(x)}
    // list.foreach { println}
   
    // filter方法
    val list1  = list.filter { x => x>3 }
    list1.foreach { println}
    
    // count方法
    val value = list1.count { x => x>3 }
    println(value)
    
    // map
    val nameList = List(
    		"hello bjsxt",
    		"hello xasxt",
    		"hello shsxt"
        )
    val mapResult:List[Array[String]] = nameList.map{ x => x.split(" ") }
    mapResult.foreach{println}    
    
    // flatmap 先map再flat
    val flatMapResult : List[String] = nameList.flatMap{ x => x.split(" ") }
    flatMapResult.foreach { println }

   /**
     * 可变的list集合
     */
    val listBuffer = new ListBuffer[String]
    listBuffer.+=("hello")
    listBuffer.+=("bj")
    listBuffer.foreach { println }
    
    listBuffer.-=("hello")

3.Set

    //创建Set
    val set1 = Set(1,2,3,4,4)
    val set2 = Set(1,2,5)
    //遍历Set集合
    //注意:set会自动去重
    set1.foreach { println}
   for(s <- set1){
      println(s)
    }

4.Map

 val map = Map(
                 "1" -> "bj",
                  2 -> "sh",
                  3 -> "gz"
                )
    val keys = map.keys
    val keyIterator = keys.iterator
    while(keyIterator.hasNext){
    val key = keyIterator.next()
    /**
      * map集合的get方法返回值是一个Option类型的对象
      * Option类型有两个子类型  分别为some None
      */
      println(key + "\t" + map.get(key).get)
    }
     
     /**
      * getOrElse原理:去集合中去取数据,若不存在返回默认值
      */
     println(map.get(4).getOrElse("default"))
    
     // Map遍历
     for(k <- map)
     println(k._1 + "\t" + k._2)
       
     map.foreach(x=>println(x._1 + "\t" + x._2))        
   
     // filter:过滤,留下符合条件的记录
     map.filter(x=>{
       Integer.parseInt(x._1 + "") >= 2
     }).foreach(println)
     
     // count:统计符合条件的记录数
     val count = map.count(x=>{
       Integer.parseInt(x._1 + "") >= 2
     })
     println(count)

5.Tuple

    /**
      * 元组 vs list
      * list创建的时候指定了泛型,那么集合中必须是这个泛型的对象
      * 元祖中可以包含任意类型的元素,这些元素使用一对小括号来封装
      * 元组的创建:最多支持22个
      */
     val t2 = Tuple2(1,"hello")
     val tt2 = (1,"hello")
     
     val t3 = Tuple3(1,true,"hello")
     val tt3 = (1,true,"hello")
     
     val moreTuple = (1,2,3)   
     
     // 元组的遍历
     val tupleIterator = tt3.productIterator
     while(tupleIterator.hasNext){
     println(tupleIterator.next())
     }
     
     // toString方法
     println(tt3.toString())
     
     //swap交换 注意只有二元组对象才会有这个方法
     val swapt2 = tt2.swap
     println(swapt2._1 + "\t" + swapt2._2)

8、字符串

    // String不可变
    val str1 = "hello bi"
    val str2 = "hello sh"
    val flag = str1.equalsIgnoreCase(str2)    
    println(flag)
    
    str1.split(" ")
    
    // StringBuffer可变
    val strBuilder = new StringBuilder
    strBuilder.append("hello\t")
    strBuilder.append("bj")
    println(strBuilder)

总结:

9、Trait特性

Scala相当于JAVA中的接口但是他比接口功能更加强大,与接口不同的是它还可以定义属性和方法的实现。
Trait可以继承多个Trait,也就是多继承,Trait定义的方式与类相似,使用关键字trait。

trait Read {
  val readType = "Read"
  val gender = "m"
  def read(name:String){
	println(name+" is reading")
  }
}

trait Listen {
  val listenType = "Listen"
  val gender = "m"
  def listen(name:String){
	println(name + " is listenning")
  }
}

class Person() extends Read with Listen{
  override val gender = "f"
}

object test {
  def main(args: Array[String]): Unit = {
    val person = new Person()
    person.read("zhangsan")
    person.listen("lisi")
    println(person.listenType)
    println(person.readType)
    println(person.gender)    
  }
}

注意:

  1. 继承的多个trait中如果有同名的方法和属性,必须要在类中使用“override”重新定义。
  2. trait中不可以传参数。

10、模式匹配

类似于JAVA中的switch case,Scala中也提供了强大的模式匹配机制,一个模式匹配包含了一系列备选项,每个都开始于关键字 case。

object Lesson_Match {
  def main(args: Array[String]): Unit = {
    val tuple = Tuple6(1,2,3f,4,"abc",55d)
    val tupleIterator = tuple.productIterator
    while(tupleIterator.hasNext){
      matchTest(tupleIterator.next())
    }   
  }

  def matchTest(x:Any) ={
    x match {
      case x:Int=> println("type is Int")
      case 1 => println("result is 1")
      case 2 => println("result is 2")
      case 3=> println("result is 3")
      case 4 => println("result is 4")
      case x:String => println("type is String")
//    case x :Double => println("type is Double")
      case _ => println("no match")
    }
  }  
}

注意:

  1. 模式匹配不仅可以匹配值,还可以匹配类型
  2. 模式匹配中,如果匹配到对应的类型或值,就不再继续往下匹配
  3. 模式匹配中,都匹配不上时,会匹配到 case _ ,相当于default

11、样例类

使用了case关键字的定义的类就是样例类,样例类是特殊的类。实现了类构造参数的getter方法(构造参数默认被声明为val),当构造参数是声明为var类型的,它将帮你实现setter和getter方法。

// 集合模式匹配
case class Person1(name:String,age:Int)

object Lesson_CaseClass {
  def main(args: Array[String]): Unit = {
    val p1 = new Person1("zhangsan",10)
    val p2 = Person1("lisi",20)
    val p3 = Person1("wangwu",30)
    
    val list = List(p1,p2,p3)
    list.foreach { x => {
      x match {
        case Person1("zhangsan",10) => println("zhangsan")
        case Person1("lisi",20) => println("lisi")
        case _ => println("no match")
      }
    } }    
  }
}

注意:

  1. 样例类默认实现了toString,equals,copy和hashCode等方法。
  2. 样例类可以new, 也可以不用new。

12、Actor

类似于JAVA中的Thread。

// Actor与Actor之间的通信
case class Message(actor:Actor,msg:Any)

class Actor1 extends Actor{
  def act(){
    while(true){
      receive{
        case  msg :Message => {
          println("i sava msg! = "+ msg.msg)
          
          msg.actor!"i love you too !"
		 }
        case msg :String => println(msg)
        case  _ => println("default msg!")
      }
    }
  }
}

class Actor2(actor :Actor) extends Actor{
  actor ! Message(this,"i love you !")
	def act(){
		while(true){
			receive{
  			case msg :String => {
  			  if(msg.equals("i love you too !")){
  			    println(msg)
  			   actor! "could we have a date !"
  			  }
  			}
  			case  _ => println("default msg!")
			}
		}
	}
}

object Lesson_Actor2 {
  def main(args: Array[String]): Unit = {
    val actor1 = new Actor1()
    actor1.start()
    val actor2 = new Actor2(actor1)
    actor2.start()
  }
}

Actor的特征:

  1. ActorModel是消息传递模型,基本特征就是消息传递
  2. 消息发送是异步的,非阻塞的
  3. 消息一旦发送成功,不能修改
  4. Actor之间传递时,自己决定决定去检查消息,而不是一直等待,是异步非阻塞的

你可能感兴趣的:(Scala基于JVM的编程语言)