文章目錄
- 引言
- 大數據介紹
- 大數據與云計算區別
- 大數據和人工智能的區別
- 大數據和傳統的分析(excel)的區別
- scala的特性
- 面向對象特性
- 函數式編程
- 函數式編程的特點:
- 函數式編程的優勢
- 靜態類型
- 擴展性
- 并發性
- 為什么要學scala
- scala安裝
- 簡單測試
- 了解Scala
- Scala來源
- Scala解釋器
- Scala集成環境配置
- 命名規范
- Scala基本語法
- 換行符
- Scala 包
- 定義包
- 引用
- Scala 數據類型
- Scala 基礎字面量
- Scala 轉義字符
- Scala變量
- 變量類型聲明
- 變量推斷
- Scala 多個變量聲明
- 其他類型
- var和val的區別
- 可變和不可變?
- Maven項目整合scala
- Scala類型轉換
- Scala訪問修飾符
- 私有(Private)成員
- 保護(Protected)成員
- 公共(Public)成員
- 作用域保護
引言
推薦學習視頻
大數據介紹
主要工作:數據統計分析(hadoop工程師、spark工程師、flink工程師、數倉工程師、BI工程師、ETL工程師 、大數據平臺工程師)
大數據與云計算區別
大數據可以做數據分析統計,而云計算可以為大數據提供一套資源利用的平臺,因此大數據很多時候基于云計算。
大數據和人工智能的區別
首先人工智能基于大數據,大數據為人工智能提供重要的海量數據
大數據和傳統的分析(excel)的區別
采用excel處理數據的方式早已不能承擔海量數據的處理
scala的特性
面向對象特性
Scala是一種純面向對象的語言,每個值都是對象,包括基本數據類型(即布爾值、數字等)在內,當然函數也是對象。
類可以被子類化,對象的數據類型以及行為由類和特質描述。
類抽象機制的擴展有兩種途徑:一種途徑是子類繼承,另一種途徑是靈活的混入機制。這兩種途徑能避免多重繼承的種種問題。
函數式編程
Scala也是一種函數式語言,其函數也能當成值來使用。Scala提供了輕量級的語法用以定義匿名函數,支持高階函數,允許嵌套多層函數,并支持柯里化。Scala的case class及其內置的模式匹配相當于函數式編程語言中常用的代數類型。
更進一步,程序員可以利用Scala的模式匹配,編寫類似正則表達式的代碼處理XML數據。
純粹的函數編程語言編寫的函數沒有變量。因此,任意一個函數,只要輸入是確定的,輸出就是確定的,這種純函數我們稱之為沒有副作用。而允許使用變量的程序設計語言,由于函數內部的變量狀態不確定,同樣的輸入,可有得到不同的輸出,因此,這種函數式有副作用的。
函數式編程的特點:
函數是一等公民
以表達式為中心
無副作用
只用純函數來構造函程序,或者說函數沒有副作用。
不修改狀態
引用透明
函數式編程的優勢
代碼簡潔,開發速度快
接近自然語言,易理解
易于代碼管理
適合并發編程
適用于熱升級
靜態類型
Scala具備類型系統,通過編譯時檢查,保證代碼的安全性和一致性。類型系統具體支持以下特性:
泛型類
協變和逆變
標注
類型參數的上下限約束
把類別和抽象類型作為對象成員
復合類型
引用自己時顯式指定類型
視圖
多態方法
擴展性
Scala的設計秉承一項事實,即在實踐中,某個領域特定的應用程序開發往往需要特定于該領域的語言擴展。Scala提供了許多獨特的語言機制,可以以庫的形式輕易無縫添加新的語言結構:
任何方法可用作前綴或后綴操作符。
可以根據預期類型自動構造閉包。
并發性
Scala使用Actor作為其并發模型,Actor是類似線程的實體,通過郵箱發收消息。Actor可以復用線程,因此可以在程序中可以使用數百萬個Actor,而線程只能創建數千個。在2.10之后的版本中,使用Akka作為其默認Actor實現。
為什么要學scala
1.優雅
框架的而用戶是應用開發程序員,API是否優雅直接影響用戶體驗
2.速度快
Scala語言表達能力強,一行代碼抵得上java多行,開發速度快,scala是靜態編譯的,所以和JRuby,Groovy比起來速度會快很多
3.能融合到Hadoop生態圈
Hadoop現在是大數據實施標準,Spark并不是要取代Hadoop,而是要完善Hadoop生態。
JVM語言大部分可能會想到Java,但java做出來的API太丑,或者想實現一個優雅的API太費勁
scala安裝
安裝參考
簡單測試
var a =10+20
可以看出scala是一種弱類型語言
了解Scala
Scala來源
Scala 是 Scalable Language 的簡寫,是一門多范式的編程語言
聯邦理工學院洛桑(EPFL)的Martin Odersky于2001年基于Funnel的工作開始設計Scala。
Funnel是把函數式編程思想和Petri網相結合的一種編程語言。
Odersky先前的工作是Generic Java和javac(Sun Java編譯器)。Java平臺的Scala于2003年底/2004年初發布。.NET平臺的Scala發布于2004年6月。該語言第二個版本,v2.0,發布于2006年3月。
截至2009年9月,最新版本是版本2.7.6 。Scala 2.8預計的特性包括重寫的Scala類庫(Scala collections library)、方法的命名參數和默認參數、包對象(package object),以及Continuation。
2009年4月,Twitter宣布他們已經把大部分后端程序從Ruby遷移到Scala,其余部分也打算要遷移。此外, Wattzon已經公開宣稱,其整個平臺都已經是基于Scala基礎設施編寫的。
Scala的預期目標是將面向對象、函數式編程和強大的類型系統結合起來,同時讓人能寫出優雅、簡介的代碼。
Scala博采眾長,Scala采用了Java和C#語法的大部分,而他們大部分借自于C,C++語法。表達式、語句和代碼塊和Java一樣,還有類、包和引用的語法。除語法之外,Scala還采用了java的其他元素,如他的基本類型、類庫和它的執行模式。
函數式編程借鑒了SML,OCaml,和F#為代表的ML家族語言很接近,Scala的隱式參數靈感來自Haskell,基于actor的并發庫來自EeLang的思想。
Scala解釋器
REPL:Read(取值)->Evaluation(求值)->Printf(打印)-> Loop(循環)。
scala解釋器被稱為REPL,會快速編譯scala代碼為字節碼,然后交給JVM來執行。
1.計算表達式
2.內置變量
3.自動補全:
在scala>命令行內,可以使用Tab鍵進行自動補全
例如:輸入a.to,按tab鍵,解析器會顯示出一下選項,tocharArray,toLowerCase,toString,toUpperCase。
Scala集成環境配置
Scala的開發工具分兩種:
Eclispe 和Idea
安裝方式:
在線和離線
idea在線方式介紹:
File->Settings->Plugins->輸入"Scala"
命名規范
基本原則:駝峰命名,命名有業務含義。
var|val orderName=“name”
Scala基本語法
Scala 基本語法需要注意以下幾點:
區分大小寫 - Scala是大小寫敏感的,這意味著標識Hello 和 hello在Scala中會有不同的含義。
類名 - 對于所有的類名的第一個字母要大寫。
如果需要使用幾個單詞來構成一個類的名稱,每個單詞的第一個字母要大寫。
示例:class MyFirstScalaClass
方法名稱 - 所有的方法名稱的第一個字母用小寫。
如果若干單詞被用于構成方法的名稱,則每個單詞的第一個字母應大寫。
示例:def myMethodName()
程序文件名 - 程序文件的名稱應該與對象名稱完全匹配(新版本不需要了,但建議保留這種習慣)。
保存文件時,應該保存它使用的對象名稱(記住Scala是區分大小寫),并追加".scala"為文件擴展名。 (如果文件名和對象名稱不匹配,程序將無法編譯)。
示例: 假設"HelloWorld"是對象的名稱。那么該文件應保存為’HelloWorld.scala"
def main(args: Array[String]) - Scala程序從main()方法開始處理,這是每一個Scala程序的強制程序入口部分。
換行符
Scala是面向行的語言,語句可以用分號(;)結束或換行符。Scala 程序里,語句末尾的分號通常是可選的。如果你愿意可以輸入一個,但若一行里僅 有一個語句也可不寫。另一方面,如果一行里寫多個語句那么分號是需要的。例如
val s = "you are a dog!"; println(s)
Scala 包
定義包
Scala 使用 package 關鍵字定義包,在Scala將代碼定義到某個包中有兩種方式:
第一種方法和 Java 一樣,在文件的頭定義包名,這種方法就后續所有代碼都放在該包中。 比如:
package com.org.analysis
class HelloWorld
第二種方法有些類似 C#,如:
package com.org.analysis {class HelloWorld
}
第二種方法,可以在一個文件中定義多個包
引用
Scala 使用 import 關鍵字引用包
import java.awt.Color // 引入Colorimport java.awt._ // 引入包內所有成員def handler(evt: event.ActionEvent) { // java.awt.event.ActionEvent... // 因為引入了java.awt,所以可以省去前面的部分
}
import語句可以出現在任何地方,而不是只能在文件頂部。import的效果從開始延伸到語句塊的結束。這可以大幅減少名稱沖突的可能性。
如果想要引入包中的幾個成員,可以使用selector(選取器):
import java.awt.{Color, Font}// 重命名成員
import java.util.{HashMap => JavaHashMap}// 隱藏成員
import java.util.{HashMap => _, _} // 引入了util包的所有成員,但是HashMap被隱藏了
注意:默認情況下,Scala 總會引入 java.lang._ 、 scala._ 和 Predef._,這里也能解釋,為什么以scala開頭的包,在使用時都是省去scala.的。
Scala 數據類型
分為值類型和引用類型
scala中所有的值都有類型,包括數值和函數。
Unit是值類型,它只有一個實例對象
Nothing是所有類型的子類,它沒有一個具體的實例對象,一個產能關鍵的應用如:拋出異常、程序exit、無限循環等。
Nothing是所有類型的子類,也是NULL的子類,Nothing沒有對象,但是可以用來定義類型。例如:如果一個方法拋出異常,則異常的返回值類型就是Nothing(雖然不會返回)
Null是所有引用類型的子類,它只有一個實例對象null,主要用來和其他的JVM語言進行互操作。
Scala 與 Java有著相同的數據類型,下表列出了 Scala 支持的數據類型:
Byte | 8位有符號補碼整數。數值區間為 -128 到 127 |
---|---|
Short | 16位有符號補碼整數。數值區間為 -32768 到 32767 |
Int | 32位有符號補碼整數。數值區間為 -2147483648 到 2147483647 |
Long | 64位有符號補碼整數。數值區間為 -9223372036854775808 到 9223372036854775807 |
Float | 32 位, IEEE 754 標準的單精度浮點數 |
Double | 64 位 IEEE 754 標準的雙精度浮點數 |
Char | 16位無符號Unicode字符, 區間值為 U+0000 到 U+FFFF |
String | 字符序列 |
Boolean | true或false |
Unit | 表示無值,和其他語言中void等同。用作不返回任何結果的方法的結果類型。Unit只有一個實例值,寫成()。 |
Null | null 或空引用 |
Nothing | Nothing類型在Scala的類層級的最底端;它是任何其他類型的子類型。 |
Any | Any是所有其他類的超類 |
AnyRef | AnyRef類是Scala里所有引用類(reference class)的基類 |
提示:
和java不同的是,scala沒有基本類型和包裝類型之分,這些類型都是類,有自己的屬性和方法。
Scala 基礎字面量
Scala 非常簡單且直觀。接下來我們會詳細介紹 Scala 字面量。
整型字面量
整型字面量用于 Int 類型,如果表示 Long,可以在數字后面添加 L 或者小寫 l 作為后綴。
0777L
浮點型字面量
如果浮點數后面有f或者F后綴時,表示這是一個Float類型,否則就是一個Double類型的。實例如下:
0.0
1e30f
3.14159f
1.0e100
.1
布爾型字面量
布爾型字面量有 true 和 false。
符號字面量
符號字面量被寫成: '<標識符> ,這里 <標識符> 可以是任何字母或數字的標識(注意:不能以數字開頭)。這種字面量被映射成預定義類scala.Symbol的實例。
如: 符號字面量 'x 是表達式 scala.Symbol(“x”) 的簡寫,符號字面量定義如下:
package scala
final case class Symbol private (name: String) {override def toString: String = "'" + name
}
字符字面量
在 Scala 字符變量使用單引號 ’ 來定義,如下:
'a'
'\u0041'
'\n'
其中 \ 表示轉義字符,其后可以跟 u0041 數字或者 \r\n 等固定的轉義字符。
字符串字面量
在 Scala 字符串字面量使用雙引號 " 來定義,如下:
"Hello,\nWorld!"
多行字符串的表示方法
多行字符串用三個雙引號來表示分隔符,格式為:""" … “”"。
實例如下:
val foo = """鋒芒極客
www.baidu.com
www.w3cschool.cc
www.pc.qq.com
以上三個地址都能訪問"""
Null 值
空值是 scala.Null 類型。
Scala.Null和scala.Nothing是用統一的方式處理Scala面向對象類型系統的某些"邊界情況"的特殊類型。
Null類是null引用對象的類型,它是每個引用類(繼承自AnyRef的類)的子類。Null不兼容值類型。
Scala 轉義字符
下表列出了常見的轉義字符:
轉義字符 | Unicode | 描述 |
---|---|---|
\b | \u0008 | 退格(BS) ,將當前位置移到前一列 |
\t | \u0009 | 水平制表(HT) (跳到下一個TAB位置) |
\n | \u000a | 換行(LF) ,將當前位置移到下一行開頭 |
\f | \u000c | 換頁(FF),將當前位置移到下頁開頭 |
\r | \u000d | 回車(CR) ,將當前位置移到本行開頭 |
\ " | \u0022 | 代表一個雙引號(")字符 |
\ ’ | \u0027 | 代表一個雙引號(")字符 |
\ | \u005c | 代表一個反斜線字符 ’ \ ’ |
0 到 255 間的 Unicode 字符可以用一個八進制轉義序列來表示,即反斜線?\?后跟 最多三個八進制。
Scala變量
在學習如何聲明變量與常量之前,我們先來了解一些變量與常量。
變量: 在程序運行過程中其值可能發生改變的量叫做變量。如:時間,年齡。
常量 在程序運行過程中其值不會發生變化的量叫做常量。如:數值 3,字符’A’。
變量聲明
在 Scala 中,使用關鍵詞 “var” 聲明變量,使用關鍵詞 “val” 聲明常量。
基本語法:
var|val 變量名[:變量類型] =變量值
使用var 或val定義一個變量
使用var(variable)聲明變量-可以被重新賦值。
使用val(value)聲明常量-引用不可變
val修飾的變量,想當于java中final修飾的變量;
聲明變量實例如下:
var myVar : String = "flag"
var myVar : String = "laughter"
以上定義了變量 myVar,我們可以修改它。
聲明常量實例如下:
val myVal : String = "Foo"
以上定義了常量 myVal,它是不能修改的。如果程序嘗試修改常量 myVal 的值,程序將會在編譯時報錯。
變量類型聲明
變量的類型在變量名之后等號之前聲明。定義變量的類型的語法格式如下:
var VariableName : DataType [= Initial Value]或val VariableName : DataType [= Initial Value]
變量推斷
在 Scala 中聲明變量和常量不一定要指明數據類型,在沒有指明數據類型的情況下,其數據類型是通過變量或常量的初始值推斷出來的。
所以,如果在沒有指明數據類型的情況下聲明變量或常量必須要給出其初始值,否則將會報錯。
var number = 10;
val charact = "Hello, Scala!";
以上實例中,number 會被推斷為 Int 類型,charact 會被推斷為 String 類型。
Scala 多個變量聲明
Scala 支持多個變量的聲明:
val xmax, ymax = 100 // xmax, ymax都聲明為100
如果方法返回值是元組,我們可以使用 val 來聲明一個元組:
scala> val pa = (40,"try")
pa: (Int, String) = (40,try)
注意事項:
1.變量名要使用字母或者下劃線開始,不要使用數字、特殊符號開始
2.變量名不建議使用關鍵字
3.變量必須賦值(因為根據值來推斷類型)
4.聲明變量時,可以不指定變量類型,編譯器會根據賦值內容自動推斷當前變量的類型。
實例:
package try_demoobject var_demo {def main(args: Array[String]): Unit = {val name:String="try"var password:String="catch";password="it";println(password);//多個變量聲明val (a,c,d)=(1,2,"abc")var e,f=100;print(a,c,d);println(e,f);//定義數組val arr=Array(1,2,3,4,5,6,7)println(arr.length)val flag:Boolean=trueval money:Double=6666.66;val salary=99999.99 //推斷類型//定義帶了類型的方法def add(a:Int,b:Int):Int=a+b;//ifval res:String=if(1>2) "false" else "true"//Unit為空類型,相當于void,使用()進行初始化var u=()println(u)println(flag)println(money)println(add(10,20))}}
其他類型
Any
Any可以接受任意的基本類型和引用類型
var any:Any=null;var anyR:Int=1var anyv:Int=2any=anyRany=anyv
AnyRef
使用AnyRef接收任意的引用類型
var anyR:AnyRef=null
AnyVal
可以使用AnyVal接收任意的基本類型
var anyV:AnyVal=u //unit
anyV=b1 //Boolean
anyV=b //Byte
Null
null值只能被推斷為Null類型,null代表空值,可以被賦值給任何AnyRef類型的常量或變量
Nothing
Nothing類型在Scala的類層級的最低端;它是任何其他類型的子類型。
當一個函數,我們確定沒有正常的返回值,可以用Nothing來指定返回的類型,這樣有一個好處,就是我們可以把返回的值(異常)賦值給其他的函數或變量(兼容性)
Option
Scala Option(選項)類型用來表示一個值是可選的(有值或無值)
val myMap:Map[String,String]=Map("key1"->"value1")val value1:Option[String]=myMap.get("key1")val value2:Option[String]=myMap.get("key2")println(value1) //Some("value1")println(value2) //Noneprintln(value1.get)
var和val的區別
1.內容是和否不變
2.val修飾的變量在編譯后,等同于加上final
3.val修飾的變量可以用lazy修飾,而var不能,使用lazy定義變量后,只有在調用該變量時才會實例化這個變量的值。而且惰性變量只能是不可變變量
//lazy修飾val的變量,表示懶加載;var不行
lazy val age=100;
可變和不可變?
可變和不可變,指的的是變量本身存的內容,值類型變量存的是數據本身,變量存的是數據的引用。
Maven項目整合scala
發現不能創建類,需要修改目錄的標注:
然后發現只能創.java的類,不能創建.scala類,將scala的sdk綁定到我們的項目:
點擊OK
Scala類型轉換
自動類型轉換
允許低類型的向高類型的轉換
val test1:String="67"val b=test1.toIntprintln(b)val c:Int=100;val d:Long=cprintln(d)val ch:Char='0'val ch1:Int=chprintln(ch1)/*定義double*/val test2:Double=1111.111val k:Int=test2.toIntprintln(k)
提示:
1.scala沒有像Java一樣的強制類型轉換
2.自動轉時,要求小類型向高類型轉換
3.高級類型向低級類型轉換的時候需要使用富類型(當前類型中的toInt()等)
Scala訪問修飾符
Scala 訪問修飾符基本和Java的一樣,分別有:private,protected,public。
如果沒有指定訪問修飾符,默認情況下,Scala 對象的訪問級別都是 public。
Scala 中的 private 限定符,比 Java 更嚴格,在嵌套類情況下,外層類甚至不能訪問被嵌套類的私有成員。
私有(Private)成員
用 private 關鍵字修飾,帶有此標記的成員僅在包含了成員定義的類或對象內部可見,同樣的規則還適用內部類。
class Outer{class try{private def f(){println("f")}class InnerMost{f() // 正確}}(new try).f() //錯誤
}
//(new try).f( ) 訪問不合法是因為 f 在 try 中被聲明為 private,而訪問不在類 try 之內。
//但在 InnerMost 里訪問 f 就沒有問題的,因為這個訪問包含在 Inner 類之內。Java中允許這兩種訪問,因為它允許外部類訪問內部類的私有成員。
保護(Protected)成員
在 scala 中,對保護(Protected)成員的訪問比 java 更嚴格一些。因為它只允許保護成員在定義了該成員的的類的子類中被訪問。而在java中,用protected關鍵字修飾的成員,除了定義了該成員的類的子類可以訪問,同一個包里的其他類也可以進行訪問。
package p{
class Super{protected def f() {println("f")}}class Sub extends Super{f()}class Other{(new Super).f() //錯誤}
}
Sub 類對 f 的訪問沒有問題,因為 f 在 Super 中被聲明為 protected,而 Sub 是 Super 的子類。相反,Other 對 f 的訪問不被允許,因為 other 沒有繼承自 Super。而后者在 java 里同樣被認可,因為 Other 與 Sub 在同一包里。
公共(Public)成員
Scala 中,如果沒有指定任何的修飾符,則默認為 public。這樣的成員在任何地方都可以被訪問。
class Outer {class try {def f() { println("f") }class InnerMost {f() // 正確}}(new try).f() // 正確因為 f() 是 public
}
作用域保護
Scala中,訪問修飾符可以通過使用限定詞強調。格式為:
private[x]
protected[x]
這里的x指代某個所屬的包、類或單例對象。如果寫成private[x],讀作"這個成員除了對[…]中的類或[…]中的包中的類及它們的伴生對像可見外,對其它所有類都是private。
package bobsrockets{package navigation{private[bobsrockets] class Navigator{protected[navigation] def useStarChart(){}class LegOfJourney{private[Navigator] val distance = 100}private[this] var speed = 200}}package launch{import navigation._object Vehicle{private[launch] val guide = new Navigator}}
}
上述例子中,類 Navigator 被標記為 private[bobsrockets] 就是說這個類對包含在 bobsrockets 包里的所有的類和對象可見。
比如說,從 Vehicle 對象里對 Navigator 的訪問是被允許的,因為對象 Vehicle 包含在包 launch 中,而 launch 包在 bobsrockets 中,相反,所有在包 bobsrockets 之外的代碼都不能訪問類 Navigator。