Scala

BigData / 2021-01-24

下载

官网

配置环境变量:

export SCALA_HOME=/usr/local/scala-2.11.12

export PATH=$PATH:$SCALA_HOME/bin

特性

  1. Java和Scala可以混编
  2. 自动类型推测
  3. 并发和分布式(Actor)
  4. 特质
  5. 模式匹配
  6. 高阶函数

基于JVM的语言,与Java无缝整合

基础

  1. Byte 8bit
  2. Short 16bit
  3. Int 32bit
  4. Long 64bit
  5. Float 32bit
  6. Double 64bit
  7. Char 16bit
  8. String
  9. Boolean
  10. Unit (void)
  11. Null 空值
  12. Nothing 所有类型的子类型,当自动类型推断推断不出来的时候给个Nothing
  13. Any 所有类型的父类,相当于Object,AnyRef AnyVal是Any的子类
  14. AnyRef 所有引用类型的父类
  15. AnyVal 所有值得超类

object:静态的

package cn.redam

class Person(nameParam:String, ageParam:Int) {

  val name = nameParam
  var age = ageParam
  var gender = 'M'

  println("new person")

  def this(nameParam:String, ageParam:Int, genderParam:Char){
    this(nameParam, ageParam)
    this.gender = genderParam
  }

  def plusAge(): Unit ={
    this.age += 1
  }
}

var 定义变量:对象可以改变的var变量

val 定义常量:建议使用,回收快,对象不能改变val变量

Object:所有属性都是静态的,可以直接通过类名.的方式调用

Class:普通的类,定义类类名后有小括号,可以传参

重载构造方法:方法中第一句this()

类中可以定义常量,变量,方法,语句

在new一个对象时,只有方法不执行(构造方法除外)

简单语法

if else 和Java 一下

1 to 3:Range(1,2,3)

1 until 3:Range(1,2)

for循环:打印小九九

for (i <- 1 until 10 ; j <- 1 until 10; if (i >= j)) {
      print(j + "*" + i + "=" + i*j + "\t")
      if (i == j)
        println()
    }

for:可以有多个条件,分号隔开

yield:收集结果组成一个vector

    val a = for (i <- 1 to 20 if (i % 2 == 0)) yield i

while:

在字符串前加上s,字符串中可以使用$引用变量

var a = 1
    while (a < 10){
      println(s"a = $a")
      a += 1
    }

方法和函数

方法:def 定义方法

方法体中return可以省略,默认返回最后一行的计算结果

def max(a:Int , b:Int) = {
      if ( a < b)
        b
      else
        a
    }

方法体的花括号可以省略

 def max(a:Int , b:Int) = if (a < b ) b else a

递归方法:需要显示声明方法的返回类型

    def fun(num:Int):Int = if (num == 1) 1 else num * fun(num - 1)

参数有默认值的方法

    def fun (a:Int = 10, b:Int = 20) = a + b
    print(fun())
    print(fun(b = 100))

可变长度参数

    def fun(str:String*) = str.foreach((item)=>println("item: " + item))
    fun("liu","jinag","ji")

匿名函数:()=>{} , 常作为参数使用

    def fun = (a:Int, b:Int) => a+b
    print(fun(1,2))

嵌套方法:方法里可以定义方法

def fun1(a:Int, b:Int) = {
      def fun2(c:Int, d:Int) = c - d
      a + b * fun2(a, b)
    }
    print(fun1(2,1))

高级函数

函数参数是函数

    def fun(f:(Int, Int)=>Int, str:String) = s"$str is " + f(100,200)
    print(fun((a:Int, b:Int) => a+b , "add"))
    print(fun((a:Int, b:Int) => a - b , "minus"))

函数的返回值是函数:显示定义返回值类型为函数, 或者使用 _ 强制转换

def fun(str:String):(Int, Int)=>String = {
      (a:Int, b:Int)=> s"$a $str $b is " + a+b
    }
    print(fun("plus").apply(1,2))

函数的参数是函数,返回值也是函数

def fun(f:(Int, Int)=>Int,s:String):(String, String)=>String ={
      (a,b)=>s"$s is " + f(1,2) + s" $a , $b"
    }
    print(fun((a,b)=>a+b, "add")("hello", "world"))

柯里化函数

def fun(a:Int, b:Int)(c:Int, d:Int) = a + b + c + d
    print(fun(1,2)(3,4))

String

scala的String就是Java的String

Array

val arr = new Array[Int](4);
    var arr1 = Array[String]("1","2","3")
    // 二维数组
    var arr2 = new Array[Array[Int]](2);
    arr2(0) = new Array[Int](3);
    arr2(1) = new Array[Int](3);
    // 遍历
    arr.foreach(item=>{print(item)})
    for (item <- arr1) {
      print(item)
    }
    arr2.foreach(item=>item.foreach(it=>print(it)))
    // 合并两个数组
    val doubleArray = Array.concat(arr, arr)
    // 填充初始化数组,长度为5
    val filledArray = Array.fill(5)("world")
    // 变长数组
    val arrayBuffer = new ArrayBuffer[Int]()
    arrayBuffer.append(1)

List

var list1 = List[Int](1,2,3)
    // 替换
    var list2 = list1.map(item => {
      item+1
    })
    // 过滤
    var list3 = list2.filter(it => it>2)
    // 变长List
    var list4 = ListBuffer[Int]()
    list4.append(3)

Set

var set1 = Set[Int](1,2,3,3,2)
    var set2 = Set[Int](3,4,5,6)
    // 交集
    var set3 = set1.intersect(set2)
    // 或者
    set3 = set1 & set2
    // 差集
    var set4 = set1.diff(set2)
    // 或者
    set4 = set1 &~ set2
    // 变长Set
    import scala.collection.mutable.Set
    var set5 = Set[Int]()
    set5.+=(1)

Map

var map1 = Map[String, String](("a","str"), ("b","str"), ("c","str"))
    print(map1.get("a").getOrElse("no value"))
    map1.keys.foreach(print)
    for (elem <- map1.values) {print(elem)}
    // 变长map
    import scala.collection.mutable.Map
    var map2 = Map[String, String]()
    map2.put("a","str")
    // 遍历:key, value
    map2.foreach((it) => {
      var key = it._1
      var value = it._2
      println(s"key=$key value=$value")
    })

Tuple

元组:一组数据

var tuple5 = (1,2,3,"str",true)
    val iterator = tuple5.productIterator
    while (iterator.hasNext)
      print(iterator.next())

Trait

相当于Java中的接口,抽象类,不能传参,继承第一个trait用extends,之后用with,Trait中的函数既可以是普通方法,也可以是抽象方法

trait Head{
  def thinking(name:String): Unit ={
    print(s"$name is thinking...")
  }
}

trait Leg{
  def running(name:String ): Unit ={
    print(s"$name is running...")
  }
  // 抽象函数
  def getLegNums():Int
}

trait Hand{
  def hit(name:String): Unit ={
    print(s"$name is hitting...")
  }
  // 抽象函数
  def getHandNums():Int
}

class Person(n:String, handsNums:Int, legsNums:Int) extends Head with Leg with Hand{
  var handsNum = handsNums
  var legsNum = legsNums
  val name = n
  thinking(name)
  running(name)
  hit(name)

  // 函数的实现
  override def getHandNums(): Int = {
    this.handsNum
  }

  // 函数实现
  override def getLegNums(): Int = {
    this.legsNums
  }
}

Match

不但可以匹配值,也可以匹配类型,_ 匹配任何数据,放在最后

从上到下匹配,成功后自动停止,会有数值转换,1.0 = 1

偏函数:匹配一个值,返回一个值

// 偏函数形式,参数类型:Int, 返回类型:String
  def parseNum : PartialFunction[Int, String] = {
    case 0 => "value is 0"
    case 1 => "value is 1"
    case 2 => "value is 2"
    case _ => "value is not 0, 1, 2"
  }

  def main(args: Array[String]): Unit = {
    parseMove("s")
    parseMove(2)
    parseMove(true)
    val nums = (1,2,3,0)
    nums.productIterator.foreach(item => println(parseNum(item.asInstanceOf[Int])))
  }

  def parseMove(o:Any): Unit ={
    o match {
        // 类型匹配
      case s:Boolean => println("wrong move...")
        // 值匹配
      case "s" => println("sleeping...")
      case "r" => println("running...")
      case "e" => println("eating...")
      case _   => println("nothing match ...")
    }

CaseClass

默认给你实现了toString,equals,hashCode方法的类

当参数是var的时候,默认实现getter,setter

样例类可以不用new

case class Person(name:String, age:Int)