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方法