一、前述
Scala Trait(特徵) 相當於 Java 的介面,實際上它比介面還功能強大。
模式匹配機制相當於java中的switch-case。
使用了case關鍵字的類定義就是樣例類(case classes),樣例類是種特殊的類。
Actor相當於Java中的多執行緒。
二、具體闡述
trait特性
1、概念理解
Scala Trait(特徵) 相當於 Java 的介面,實際上它比介面還功能強大。
與介面不同的是,它還可以定義屬性和方法的實現。
一般情況下Scala的類可以繼承多個Trait,從結果來看就是實現了多重繼承。Trait(特徵) 定義的方式與類類似,但它使用的關鍵字是 trait。
2、舉例:trait中帶屬性帶方法實現
- 繼承的多個trait中如果有同名的方法和屬性,必須要在類中使用“override”重新定義。
- 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) } }
3、舉例:trait中帶方法不實現
object Lesson_Trait2 { def main(args: Array[String]): Unit = { val p1 = new Point(1,2) val p2 = new Point(1,3) println(p1.isEqule(p2)) println(p1.isNotEqule(p2)) } } trait Equle{ def isEqule(x:Any) :Boolean def isNotEqule(x : Any) = { !isEqule(x) } } class Point(x:Int, y:Int) extends Equle { val xx = x val yy = y def isEqule(p:Any) = { p.isInstanceOf[Point] && p.asInstanceOf[Point].xx==xx } }
模式匹配match
1、概念理解:
Scala 提供了強大的模式匹配機制,應用也非常廣泛。
一個模式匹配包含了一系列備選項,每個都開始於關鍵字 case。
每個備選項都包含了一個模式及一到多個表示式。箭頭符號 => 隔開了模式和表示式。
2、程式碼及注意點
- 模式匹配不僅可以匹配值還可以匹配型別
- 從上到下順序匹配,如果匹配到則不再往下匹配
- 都匹配不上時,會匹配到case _ ,相當於default
- match 的最外面的”{ }”可以去掉看成一個語句
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()) } } /** * 注意點: * 1.模式匹配不僅可以匹配值,還可以匹配型別 * 2.模式匹配中,如果匹配到對應的型別或值,就不再繼續往下匹配 * 3.模式匹配中,都匹配不上時,會匹配到 case _ ,相當於default */ 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") } } }
樣例類(case classes)
1、概念理解
使用了case關鍵字的類定義就是樣例類(case classes),樣例類是種特殊的類。實現了類構造引數的getter方法(構造引數預設被宣告為val),當構造引數是宣告為var型別時,它幫你實現setter和getter方法。
- 樣例類預設幫你實現了toString,equals,copy和hashCode等方法。
- 樣例類可以new, 也可以不用new
2、例子:結合模式匹配的程式碼
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") } } } } }
Actor Model
1、概念理解
Actor Model是用來編寫平行計算或分散式系統的高層次抽象(類似java中的Thread)讓程式設計師不必為多執行緒模式下共享鎖而煩惱,被用在Erlang 語言上, 高可用性99.9999999 % 一年只有31ms 當機Actors將狀態和行為封裝在一個輕量的程式/執行緒中,但是不和其他Actors分享狀態,每個Actors有自己的世界觀,當需要和其他Actors互動時,通過傳送事件和訊息,傳送是非同步的,非堵塞的(fire-andforget),傳送訊息後不必等另外Actors回覆,也不必暫停,每個Actors有自己的訊息佇列,進來的訊息按先來後到排列,這就有很好的併發策略和可伸縮性,可以建立效能很好的事件驅動系統。
Actor的特徵:
- ActorModel是訊息傳遞模型,基本特徵就是訊息傳遞
- 訊息傳送是非同步的,非阻塞的
- 訊息一旦傳送成功,不能修改
- Actor之間傳遞時,自己決定決定去檢查訊息,而不是一直等待,是非同步非阻塞的
2、什麼是Akka
Akka 是一個用 Scala 編寫的庫,用於簡化編寫容錯的、高可伸縮性的 Java 和Scala 的 Actor 模型應用,底層實現就是Actor,Akka是一個開發庫和執行環境,可以用於構建高併發、分散式、可容錯、事件驅動的基於JVM的應用。使構建高併發的分散式應用更加容易。
spark1.6版本之前,spark分散式節點之間的訊息傳遞使用的就是Akka,底層也就是actor實現的。1.6之後使用的netty傳輸。
3、例:Actor簡單例子傳送接收訊息
import scala.actors.Actor class myActor extends Actor{ def act(){ while(true){ receive { case x:String => println("save String ="+ x) case x:Int => println("save Int") case _ => println("save default") } } } } object Lesson_Actor { def main(args: Array[String]): Unit = { //建立actor的訊息接收和傳遞 val actor =new myActor() //啟動 actor.start() //傳送訊息寫法 actor ! "i love you !" } }
4、例: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() } }
附例:WordCount
import org.apache.spark.SparkConf import org.apache.spark.SparkContext import org.apache.spark.rdd.RDD import org.apache.spark.rdd.RDD.rddToPairRDDFunctions object WordCount { def main(args: Array[String]): Unit = { val conf = new SparkConf() conf.setMaster("local").setAppName("WC") val sc = new SparkContext(conf) val lines :RDD[String] = sc.textFile("./words.txt") val word :RDD[String] = lines.flatMap{lines => { lines.split(" ") }} val pairs : RDD[(String,Int)] = word.map{ x => (x,1) } val result = pairs.reduceByKey{(a,b)=> {a+b}} result.sortBy(_._2,false).foreach(println) //簡化寫法 lines.flatMap { _.split(" ")}.map { (_,1)}.reduceByKey(_+_).foreach(println) } }