1. 程式人生 > >Scala重點基礎

Scala重點基礎

Scala語言特點 優雅 快

object 相當於一個靜態的物件 def 方法 unit 相當於void

一、資料型別 Byte Short Long Float Double Char String Boolean Unit(=void) Null Any Nothing AnyRef

符號字面量: 寫法:<識別符號> `x <識別符號>可以是任何字母或數字的標識(不能以數字開頭) 這種字面量被對映成預定義類scala.Symbol的例項。

二、變數:

1、變數宣告
var 變數名:變數型別 = 變數值
變數宣告一定需要初始值,否則會報錯。

三、方法定義 格式:def methodName(引數名:引數型別):返回值 = 方法體

     不指定返回值根據方法體自行推倒:
      def methodName(引數名:引數型別) = {方法體}
     無返回值:
        def methodName(引數名:引數型別) = {沒有返回值方法體}
      不傳遞引數
      def methodName() = {方法體}
      若無引數傳遞可以不加()

       val f3:(Int,Int) => Int={(x,y) => x*y}

       filter  攔截

四、方法和函式的區別

1、在java中函式和方法是沒有區別的
2、在scala中
    -函式可以作為引數傳入到方法中執行
    -函式可以呼叫方法
        |-方法轉換為函式
        |-val f1= m _ (m是一個方法可以通過_轉換成函式)

五、wordCount實現

1、切分
2、壓平
var arr2=arr.flatMap(x=>x.split(" "))

arr2: Array[String] = Array(Hadoop, Hive, Sqoop, 
Hive, Hbase, Hive, Hadoop, Spark)

3、計數//可省略
4、合併彙總(groupby)
var arr3=arr2.groupBy(x=>x)
arr3: scala.collection.immutable.Map[String,Array[String]]
= Map(Sqoop -> Array(Sqoop),
Hbase -> Array(Hbase),
Hive -> Array(Hive, Hive, Hive)
, Spark -> Array(Spark),
Hadoop -> Array(Hadoop, Hadoop))
scala> var arr4=arr3.map(x=>(x._1,x._2.length))
arr4: scala.collection.immutable.Map[String,Int] = Map(Sqoop -> 1, Hbase -> 1, Hive -> 3, Spark -> 1, Hadoop -> 2)
TopN:
object ScalaWordCount {
def main(args: Array[String]): Unit = {
//造資料
var list=List("  I Love cw ","cw hava a big JB","cw is very    filthy")
//資料轉換採用鏈式程式設計
var ans=list.flatMap(line=>line.trim()
  .split(" ")
  .filterNot(word=>word.isEmpty))
  .groupBy(x=>x)
  .map(x=>(x._1,x._2.length))
  .toList.sortBy(x=> - x._2)
  .take(3)
print(ans.toString())
//對每一行資料進行切割
//轉換,去掉單詞空格
//資料過濾   .filterNot(word=>word.isEmpty)
//將單詞轉換為二元陣列

} } —————————————————————–+

函數語言程式設計

使用java實現函數語言程式設計 介面==規則==函式

jdk1.8 Lambda表示式實現函數語言程式設計

->

陣列 set map list 可變可不變 += ++= -= remove

當var建立

伴生物件 Object 跟類名相同 且在同一個檔案中 可以訪問private的屬性和方法

private 當前類和伴生物件 private[this] 只在當前類中可以使用

指定包訪問許可權 private[package] classname

構造器(構造方法) -主構造器 :class className(val/var propertyName:propertyTpe,…) [ -輔助構造器 :this(){}

跟類名交織在一起的叫主構造器,主構造器中的屬性會成為這個類的成員變數
輔助構造器是對主構造器的擴充套件

輔助構造器第一行一定要先呼叫主構造器
輔助構造器的變數不用val var定義
def this(id:Long){}

沒有加var/val不會成為成員變數只能在內部使用

class eople paivate(引數)//私有的構造器只能在伴生物件中使用

物件和例項是兩回事 物件 object 靜態物件 單例物件 例項 new

apply方法: object名字後面跟括號,括號中有引數,執行時會尋找引數個數一樣的apply方法

7、 Scala函式的求值策略

 Scala中,有兩種函式引數的求值策略  Call By Value:對函式實參求值,且僅求一次  Call By Name:函式實參每次在函式體內被用到時都會求值

繼承實現特質

-重寫非抽象方法必須加overwrite

-trait(類似java中的介面) (特質) 可以定義有實現的方法

-在scala中,第一個繼承和實現都使用extend

-動態實現特質 在Object中new出來後with 特質

=*=多型:

必須重寫 介面指向實現類 父類引用指向子類

模式匹配(switch) 一旦一個匹配上了就不會繼續往下匹配了 匹配字串內容、陣列、List、元組、資料型別、物件

det contentMatch(str:string)=str match{ case “value” => println(“”) case “value” => println(“”) case _=> }

特殊陣列 0::Nil 只有0元素是的List 7::9::Nil 只有7,9元素的ist x::y::z 只有三個元素的List m::n 擁有head和tail的陣列

閉包(函式的巢狀): 在一個函式定義中,包含另外一個函式的定義; 並且在內函式中可以訪問外函式中的變數。

def mulBy(factor:Double)=(x:Double)=>x*factor var triple = mulBy(3) triple: Double => Double =

val half = mulBy(0.5) half: Double => Double =

println(triple(10)+” “+half(8)) 30.0 4.0

柯里化:

def add(x:Int,y:Int) =x+y def add(x:Int)(y:Int) =x+y

包: scala中的包和java中的包一樣 scala中的包可以巢狀 import可以寫在任何地方

包物件:

-包可以包含類、物件和特質,但不能包含函式或者變數的定義。很不幸,這是Java虛擬機器的侷限。
-把工具函式或者常量新增到包而不是某個Utils物件,這是更加合理的做法。Scala中,包物件的出現正是為了解決這個侷限。
-Scala中的包物件:常量,變數,方法,類,物件,trait(特質)

Scala中檔案的訪問 val source=scala.io.Source.fromFile(“filePath”) 讀取行: sourec.getLnes()

讀取字元: for(c<-source)

指定字符集 val source=scala.io.Source.fromURL(“filePath”,”Utf-8”)

Scala不支援二進位制讀取 但是可以通過呼叫java的InputStream來進行讀取

寫入文字檔案 PrintWriter() 呼叫的是java的Api

Scala中的集合

Scala的集合有三大類:序列Seq、集Set、對映Map,所有的集合都擴充套件自Iterable特質 在Scala中集合有可變(mutable)和不可變(immutable)兩種型別,immutable型別的集合初始化後就不能改變了(注意與val修飾的變數進行區別)

可變集合和不可變集合

-序列 Vector和Range

 Vector是ArrayBuffer的不可變版本,是一個帶下標的序列  Range表示一個整數序列

Scala的case class就是在普通的類定義前加case這個關鍵字, 然後你可以對這些類來模式匹配

scala語言的高階特性 1、泛型類 使用[]來定義泛型引數

什麼是泛型函式 函式和方法也可以帶型別引數。和泛型類一樣,我們需要把型別引數放在 方法名之後

3、 Upper Bounds 與 Lower Bounds

 S <: T 這是型別上界的定義。也就是S必須是型別T的子類(或本身,自己也可以認為是自己的子類。

 U >: T 這是型別下界的定義。也就是U必須是型別T的父類(或本身,自己也可以認為是自己的父類)。

視圖鑑定:<%

它比<:適用範圍更廣,允許所有的子型別,還允許隱 試轉換過去的型別。

使用試圖鑑定,取代泛型上界

Scala沒有定義的轉換 使用時需要建立轉換規則

協變和逆變:

scala的協變:泛型變數的值可以是本身型別或者其子類的型別

Scala的類或特質的泛型定義中,如果在型別引數前面加入+ 符號,就可以使類或特質變為協變。

逆變: 在類或特徵的定義中,在型別引數之前加上一個-符號, 就可定義逆變範型類和特徵了。

Scala的逆變:泛型變數的值可以是本身型別或者其父類的型別

隱式轉換函式 隱式轉換函式指的是以implicit關鍵字申明的帶有單個引數的函式

使用implicit申明的函式引數叫做隱式引數。我們也可以使用隱式引數實現隱式的轉換

8、 隱式類 所謂隱式類: 就是對類增加implicit 限定的類 ,其作用主要是對類的功能加強!

/** * scala的隱式轉換 */ object ImplicitClass { implicit class Cala(x:Int){ def add(a:Int): Int = { a+x } }

def main(args: Array[String]): Unit = { println(1.add(2)) } }

隱式類執行的過程: 1、當1.add(2),scala的編譯器不會立即報錯;在當前域中查詢,又沒有implicit修飾的, 同時可以將Int作為引數的構造器,並且具有add方法的類,最終找到Calc 2、利用隱式類執行add方法