Scala

Scala介紹 html

1.Spark中使用的是Sacla2.10。 java

2.Scala官網6個特徵。 程序員

    1).Java和scala能夠混編 apache

    2).類型推測(自動推測類型) windows

    3).併發和分佈式(Actor) 數組

    4).特質,特徵(相似java中interfaces 和 abstract結合) 多線程

    5).模式匹配(相似java switch) 併發

    6).高階函數 app

Scala安裝使用 eclipse

  1. windows安裝,配置環境變量
  • 官網下載scala2.10http://www.scala-lang.org/download/2.10.4.html
  • 下載好後安裝。雙擊msi包安裝,記住安裝的路徑。
  • 配置環境變量(和配置 jdk 同樣)
    • 新建 SCALA_HOME

    • 上個步驟完成後,編輯Path變量,在後面追加以下:

    ;%SCALA_HOME%\bin;%SCALA_HOME%\jre\bin

  • 打開 cmd, 輸入: scala - version 看是否顯示版本號,肯定是否安裝成功

     

  1. eclipse 配置scala插件
  • 下載插件(必定要對應 eclipse 版本下載)

    http://scala-ide.org/download/prev-stable.html

  • 下載好 zip 包後,解壓以下:

  • featuresplugins兩個文件夾拷貝到eclipse安裝目錄中的" dropins/scala"目錄下。進入dropins,新建scala文件夾,將兩個文件夾拷貝到"dropins/scala"下
  1. scala ide

    下載網址:http://scala-ide.org/download/sdk.html

  2. idea 中配置scala插件
  • 打開 idea,close 項目後,點擊 Configure->Plugins

  • 搜索 scala ,點擊 Install 安裝

  • 設置 jdk ,打開 Project Structure, 點擊 new 選擇安裝好的 jdk 路徑

  • 建立 scala 項目,配置 scala sdk(Software Development Kit)

    點擊第三步,彈出選擇SDK,點擊Browse選擇本地安裝的Scala目錄。選擇system.

Scala基礎

  1. 數據類型

  1. 變量和常量的聲明
  • 定義變量或者常量的時候,也能夠寫上返回的類型,通常省略,如:val a:Int = 10
  • 常量不可再賦值

/**

* 定義變量和常量

* 變量 : var 定義 ,可修改

* 常量 : val 定義,不可修改

*/

var name = "zhangsan"

println(name)

name ="lisi"

println(name)

val gender = "m"

// gender = "m"//錯誤,不能給常量再賦值

  1. 類和對象
  • 建立類

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())

}

}

 

  • 伴生類和伴生對象

class Person(xname :String , xage :Int){

var name = Person.name

val age = xage

var gender = "m"

def this(name:String,age:Int,g:String){

this(name,age)

gender = g

}

 

def sayName() = {

"my name is "+ name

}

 

}

 

object Person {

val name = "zhangsanfeng"

 

def main(args: Array[String]): Unit = {

val person = new Person("wagnwu",10,"f")

println(person.age);

println(person.sayName())

println(person.gender)

}

}

 

注意點:

  • 建議類名首字母大寫 ,方法首字母小寫,類和方法命名建議符合駝峯命名法。
  • scala 中的object是單例對象,至關於java中的工具類,能夠當作是定義靜態的方法的類。object不能夠傳參數。另:Trait不能夠傳參數
  • scala 中的 class 類默承認以傳參數,默認的傳參數就是默認的構造函數。

    重寫構造函數的時候,必需要調用默認的構造函數。

  • class 類屬性自帶getter setter方法。
  • 使用object時,不用new,使用class時要new ,而且new的時候,class中除了方法不執行,其餘都執行。
  • 若是在同一個文件中,object對象和class類的名稱相同,則這個對象就是這個類的伴生對象,這個類就是這個對象的伴生類。能夠互相訪問私有變量。

 

  1. if else

/**

* if else

*/

val age =18

if (age < 18 ){

    println("no allow")

}else if (18<=age&&age<=20){

    println("allow with other")

}else{

    println("allow self")

}

 

  1. for ,while,do…while
    1. tountil 的用法(不帶步長,帶步長區別)

/**

* tountil

* 例:

* 1 to 10 返回110Range數組,包含10

* 1 until 10 返回110 Range數組 ,不包含10

*/

 

println(1 to 10 )//打印 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

println(1.to(10))//與上面等價,打印 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

 

println(1 to (10 ,2))//步長爲2,從1開始打印 1,3,5,7,9

println(1.to(10, 2))

 

println(1 until 10 ) //不包含最後一個數,打印 1,2,3,4,5,6,7,8,9

println(1.until(10))//與上面等價

 

println(1 until (10 ,3 ))//步長爲2,從1開始打印,打印1,4,7

  1. 建立for循環

/**

* for 循環

*

*/

for( i <- 1 to 10 ){

println(i)

}

  1. 建立多層for循環

//能夠分號隔開,寫入多個list賦值的變量,構成多層for循環

//scala 不能寫count++ count-- 只能寫count+

var count = 0;

for(i <- 1 to 10; j <- 1 until 10){

println("i="+ i +",    j="+j)

count += 1

}

println(count);

 

//例子: 打印小九九

for(i <- 1 until 10 ;j <- 1 until 10){

if(i>=j){

     print(i +" * " + j + " = "+ i*j+"    ")

 

}

if(i==j ){

println()

}

 

}

 

  1. for循環中能夠加條件判斷,可使用分號隔開,也能夠不使用分號

//能夠在for循環中加入條件判斷

for(i<- 1 to 10 ;if (i%2) == 0 ;if (i == 4) ){

println(i)

}

 

  1. scala中不能使用count++count—只能使用count = count+1 count += 1
  2. for循環用yield 關鍵字返回一個集合
  3. while循環,while(){}do {}while()

 

//for中的符合條件的元素經過yield關鍵字返回成一個集合

val list = for(i <- 1 to 10 ; if(i > 5 )) yield i

for( w <- list ){

println(w)

}

 

/**

* while 循環

*/

var index = 0

while(index < 100 ){

    println(""+index+"while 循環")

index += 1

}

index = 0

do{

    index +=1

    println(""+index+"do while 循環")

}while(index <100 )

 

Scala函數

  1. Scala函數的定義
  • 有參函數
  • 無參函數

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))

注意點:

  • 函數定義語法 def來定義
  • 能夠定義傳入的參數,要指定傳入參數的類型
  • 方法能夠寫返回值的類型也能夠不寫,會自動推斷,有時候不能省略,必須寫,好比在遞歸函數中或者函數的返回值是函數類型的時候。
  • scala中函數有返回值時,能夠寫return,也能夠不寫return,會把函數中最後一行當作結果返回。當寫return時,必需要寫函數的返回值。
  • 若是返回值能夠一行搞定,能夠將{}省略不寫
  • 傳遞給方法的參數能夠在方法中使用,而且scala規定方法的傳過來的參數爲val的,不是var的。
  • 若是去掉方法體前面的等號,那麼這個方法返回類型一定是Unit的。這種說法不管方法體裏面什麼邏輯都成立,scala能夠把任意類型轉換爲Unit.假設,裏面的邏輯最後返回了一個string,那麼這個返回值會被轉換成Unit,而且值會被丟棄。
  1. 遞歸函數

/**

* 遞歸函數

* 5的階乘

*/

def fun2(num :Int) :Int= {

if(num ==1)

num

else

num * fun2(num-1)

}

print(fun2(5))

  1. 包含參數默認值的函數
  • 默認值的函數中,若是傳入的參數個數與函數定義相同,則傳入的數值會覆蓋默認值。
  • 若是不想覆蓋默認值,傳入的參數個數小於定義的函數的參數,則須要指定參數名稱。

/**

* 包含默認參數值的函數

* 注意:

* 1.默認值的函數中,若是傳入的參數個數與函數定義相同,則傳入的數值會覆蓋默認值

* 2.若是不想覆蓋默認值,傳入的參數個數小於定義的函數的參數,則須要指定參數名稱

*/

def fun3(a :Int = 10,b:Int) = {

println(a+b)

}

fun3(b=2)

 

  1. 可變參數個數的函數
  • 多個參數用逗號分開

/**

* 可變參數個數的函數

* 注意:多個參數逗號分開

*/

def fun4(elements :Int*)={

var sum = 0;

for(elem <- elements){

sum += elem

}

sum

}

println(fun4(1,2,3,4))

  1. 匿名函數
    1. 有參匿名函數
    2. 無參匿名函數
    3. 有返回值的匿名函數
  • 能夠將匿名函數返回給val定義的值
  • 匿名函數不能顯式聲明函數的返回類型

/**

* 匿名函數

* 1.有參數匿名函數

* 2.無參數匿名函數

* 3.有返回值的匿名函數

* 注意:

* 能夠將匿名函數返回給定義的一個變量

*/

//有參數匿名函數

val value1 = (a : Int) => {

println(a)

}

value1(1)

//無參數匿名函數

val value2 = ()=>{

println("我愛尚學堂")

}

value2()

//有返回值的匿名函數

val value3 = (a:Int,b:Int) =>{

a+b

}

println(value3(4,4))

  1. 嵌套函數

/**

* 嵌套函數

* 例如:嵌套函數求5的階乘

*/

def fun5(num:Int)={

def fun6(a:Int,b:Int):Int={

if(a == 1){

b

}else{

fun6(a-1,a*b)

}

}

fun6(num,1)

}

println(fun5(5))

 

  1. 偏應用函數

    偏應用函數是一種表達式,不須要提供函數須要的全部參數,只須要提供部分,或不提供所需參數。

/**

* 偏應用函數

*/

def log(date :Date, s :String)= {

println("date is "+ date +",log is "+ s)

}

 

val date = new Date()

log(date ,"log1")

log(date ,"log2")

log(date ,"log3")

 

//想要調用log,以上變化的是第二個參數,能夠用偏應用函數處理

val logWithDate = log(date,_:String)

logWithDate("log11")

logWithDate("log22")

logWithDate("log33")

  1. 高階函數

    函數的參數是函數,或者函數的返回類型是函數,或者函數的參數和函數的返回類型是函數的函數。

  • 函數的參數是函數
  • 函數的返回是函數
  • 函數的參數和函數的返回是函數

/**

* 高階函數

* 函數的參數是函數        或者函數的返回是函數        或者函數的參數和返回都是函數

*/

 

//函數的參數是函數

def hightFun(f : (Int,Int) =>Int, a:Int ) : Int = {

f(a,100)

}

def f(v1 :Int,v2: Int):Int = {

v1+v2

}

 

println(hightFun(f, 1))

 

//函數的返回是函數

//12,3,4相加

def hightFun2(a : Int,b:Int) : (Int,Int)=>Int = {

def f2 (v1: Int,v2:Int) :Int = {

v1+v2+a+b

}

f2

}

println(hightFun2(1,2)(3,4))

 

//函數的參數是函數,函數的返回是函數

def hightFun3(f : (Int ,Int) => Int) : (Int,Int) => Int = {

f

}

println(hightFun3(f)(100,200))

println(hightFun3((a,b) =>{a+b})(200,200))

//以上這句話還能夠寫成這樣

//若是函數的參數在方法體中只使用了一次 那麼能夠寫成_表示

println(hightFun3(_+_)(200,200))

  1. 柯里化函數
  • 能夠理解爲高階函數的簡化

/**

* 柯里化函數

*/

def fun7(a :Int,b:Int)(c:Int,d:Int) = {

a+b+c+d

}

println(fun7(1,2)(3,4))

Scala字符串

  1. String
  2. StringBuilder 可變
  3. string操做方法舉例
  • 比較:equals
  • 比較忽略大小寫:equalsIgnoreCase
  • indexOf:若是字符串中有傳入的assci碼對應的值,返回下標

/**

* String && StringBuilder

*/

val str = "abcd"

val str1 = "ABCD"

 

println(str.indexOf(97))

println(str.indexOf("b"))

 

println(str==str1)

/**

* compareToIgnoreCase

*

* 若是參數字符串等於此字符串,則返回值 0

* 若是此字符串小於字符串參數,則返回一個小於 0 的值;

* 若是此字符串大於字符串參數,則返回一個大於 0 的值。

*

*/

println(str.compareToIgnoreCase(str1))

 

val strBuilder = new StringBuilder

strBuilder.append("abc")

// strBuilder.+('d')

strBuilder+ 'd'

// strBuilder.++=("efg")

strBuilder++= "efg"

// strBuilder.+=('h')

strBuilder+= 'h'

strBuilder.append(1.0)

strBuilder.append(18f)

println(strBuilder)

 

String方法:(見附件)

 

集合

數組

  1. 建立數組
  • new Array[Int](10)

    賦值:arr(0) = xxx

  • Array[String]("s1","s2","s3")
  1. 數組遍歷
  • for
  • foreach
  1. 建立一維數組和二維數組
  2. 數組中方法舉例
  • Array.concate:合併數組
  • Array.fill(5)("bjsxt"):建立初始值的定長數組

建立兩種方式:

/**

* 建立數組兩種方式:

* 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

遍歷兩種方式:

/**

* 遍歷兩種方式

*/

for(i <- arr1){

     println(i)

}

arr1.foreach(i => {

println(i)

})

 

for(s <- arr2){

println(s)

}

arr2.foreach {

x => println(x)

}

 

建立二維數組

/**

* 建立二維數組和遍歷

*/

val arr3 = new Array[Array[String]](3)

arr3(0)=Array("1","2","3")

arr3(1)=Array("4","5","6")

arr3(2)=Array("7","8","9")

for(i <- 0 until arr3.length){

for(j <- 0 until arr3(i).length){

print(arr3(i)(j)+"    ")

}

println()

}

 

var count = 0

for(arr <- arr3 ;i <- arr){

if(count%3 == 0){

println()

}

print(i+"    ")

count +=1

}

 

arr3.foreach { arr => {

arr.foreach { println }

}}

 

 

val arr4 = Array[Array[Int]](Array(1,2,3),Array(4,5,6))

arr4.foreach { arr => {

arr.foreach(i => {

println(i)

})

}}

println("-------")

for(arr <- arr4;i <- arr){

println(i)

}

 

 

數組中的方法:

 

list

  1. 建立list

val list = List(1,2,3,4)

  • Nil長度爲0list
  1. list 遍歷

    foreach for

  2. list方法舉例
  • filter:過濾元素
  • count:計算符合條件的元素個數
  • map:對元素操做
  • flatmap :壓扁扁平,mapflat

 

//建立

val list = List(1,2,3,4,5)

 

//遍歷

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

val flatMapResult : List[String] = nameList.flatMap{ x => x.split(" ") }

flatMapResult.foreach { println }

  1. list方法總結

set

  1. 建立set

注意:set集合會自動去重

  1. set遍歷

foreachfor

  1. set方法舉例
  • 交集:intersect ,&
  • 差集: diff ,&~
  • 子集:subsetOf
  • 最大:max
  • 最小:min
  • 轉成數組,toList
  • 轉成字符串:mkString("~")
  1. set方法總結

//建立

val set1 = Set(1,2,3,4,4)

val set2 = Set(1,2,5)

//遍歷

//注意:set會自動去重

set1.foreach { println}

for(s <- set1){

println(s)

}

println("*******")

/**

* 方法舉例

*/

 

//交集

val set3 = set1.intersect(set2)

set3.foreach{println}

val set4 = set1.&(set2)

set4.foreach{println}

println("*******")

//差集

set1.diff(set2).foreach { println }

set1.&~(set2).foreach { println }

//子集

set1.subsetOf(set2)

 

//最大值

println(set1.max)

//最小值

println(set1.min)

println("****")

 

//轉成數組,list

set1.toArray.foreach{println}

println("****")

set1.toList.foreach{println}

 

//mkString

println(set1.mkString)

println(set1.mkString("\t"))

 

set方法總結

 

map

  1. map建立
  • Map1 –>"bjsxt'
  • Map((1,"bjsxt"))

注意:建立map時,相同的key被後面的相同的key頂替掉,只保留一個

val map = Map(

"1" -> "bjsxt",

2 -> "shsxt",

(3,"xasxt")

)

 

  1. 獲取map的值
  • map.get("1").get
  • map.get(100).getOrElse("no value"):若是map中沒有對應項,賦值爲getOrElse傳的值。

//獲取值

println(map.get("1").get)

val result = map.get(8).getOrElse("no value")

println(result)

  1. 遍歷map
  • for,foreach

//map遍歷

for(x <- map){

println("====key:"+x._1+",value:"+x._2)

}

map.foreach(f => {

println("key:"+ f._1+" ,value:"+f._2)

})

  1. 遍歷key
  • map.keys

//遍歷key

val keyIterable = map.keys

keyIterable.foreach { key => {

println("key:"+key+", value:"+map.get(key).get)

} }

println("---------")

 

  1. 遍歷value
  • map.values

//遍歷value

val valueIterable = map.values

valueIterable.foreach { value => {

println("value: "+ value)

} }

 

  1. 合併map
  • ++ 例:map1.++(map2) --map1中加入map2
  • ++: 例:map1.++:(map2) –map2中加入map1

注意:合併map會將map中的相同keyvalue替換

//合併map

val map1 = Map(

(1,"a"),

(2,"b"),

(3,"c")

)

val map2 = Map(

(1,"aa"),

(2,"bb"),

(2,90),

(4,22),

(4,"dd")

)

map1.++:(map2).foreach(println)

 

  1. map中的方法舉例
  • filter:過濾,留下符合條件的記錄
  • count:統計符合條件的記錄數
  • containsmap中是否包含某個key
  • exist:符合條件的記錄存在不存在

/**

* map方法

*/

//count

val countResult = map.count(p => {

p._2.equals("shsxt")

})

println(countResult)

 

//filter

map.filter(_._2.equals("shsxt")).foreach(println)

 

//contains

println(map.contains(2))

 

//exist

println(map.exists(f =>{

f._2.equals("xasxt")

 

}))

 

Map方法總結

元組

  1. 元組定義

    與列表同樣,與列表不一樣的是元組能夠包含不一樣類型的元素。元組的值是經過將單個的值包含在圓括號中構成的。

  2. 建立元組與取值
  • val tuple = new Tuple1 可使用new
  • val tuple2 = Tuple1,2 能夠不使用new,也能夠直接寫成val tuple3 =1,2,3
  • 取值用"._XX" 能夠獲取元組中的值

注意:tuple最多支持22個參數

//建立,最多支持22

val tuple = new Tuple1(1)

val tuple2 = Tuple2("zhangsan",2)

val tuple3 = Tuple3(1,2,3)

val tuple4 = (1,2,3,4)

val tuple18 = Tuple18(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18)

val tuple22 = new Tuple22(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22)

 

//使用

println(tuple2._1 + "\t"+tuple2._2)

val t = Tuple2((1,2),("zhangsan","lisi"))

println(t._1._2)

 

  1. 元組的遍歷

    tuple.productIterator獲得迭代器,進而遍歷

//遍歷

val tupleIterator = tuple22.productIterator

while(tupleIterator.hasNext){

println(tupleIterator.next())

}

  1. swap,toString 方法

    注意:swap元素翻轉,只針對二元組

/**

* 方法

*/

//翻轉,只針對二元組

println(tuple2.swap)

 

//toString

println(tuple3.toString())

 

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)

 

}

}

 

  1. 舉例: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

每一個備選項都包含了一個模式及一到多個表達式。箭頭符號 => 隔開了模式和表達式。

  1. 代碼及注意點
  • 模式匹配不只能夠匹配值還能夠匹配類型
  • 從上到下順序匹配,若是匹配到則再也不往下匹配
  • 都匹配不上時,會匹配到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類型的,它將幫你實現settergetter方法。

  • 樣例類默認幫你實現了toString,equalscopyhashCode等方法。
  • 樣例類能夠new, 也能夠不用new
  1. 例子:結合模式匹配的代碼

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之間傳遞時,本身決定決定去檢查消息,而不是一直等待,是異步非阻塞的

什麼是Akka

Akka 是一個用 Scala 編寫的庫,用於簡化編寫容錯的、高可伸縮性的 Java 和Scala 的 Actor 模型應用,底層實現就是Actor,Akka是一個開發庫和運行環境,能夠用於構建高併發、分佈式、可容錯、事件驅動的基於JVM的應用。使構建高併發的分佈式應用更加容易。

spark1.6版本以前,spark分佈式節點之間的消息傳遞使用的就是Akka,底層也就是actor實現的。1.6以後使用的netty傳輸。

  1. 例: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 !"

 

}

}

 

  1. 例:ActorActor之間通訊

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)

 

}

}

相關文章
相關標籤/搜索