Scala簡(jiǎn)介
Scala是一種多范式的編程語(yǔ)言匀泊,其設(shè)計(jì)的初衷是要集成面向?qū)ο缶幊毯秃瘮?shù)式編程的各種特性。Scala運(yùn)行于Java平臺(tái)(Java虛擬機(jī))猎贴,并兼容現(xiàn)有的Java程序班缎。它也能運(yùn)行于CLDC配置的Java ME中。目前還有另一.NET平臺(tái)的實(shí)現(xiàn)她渴,不過(guò)該版本更新有些滯后达址。Scala的編譯模型(獨(dú)立編譯,動(dòng)態(tài)類加載)與Java和C#一樣趁耗,所以Scala代碼可以調(diào)用Java類庫(kù)(對(duì)于.NET實(shí)現(xiàn)則可調(diào)用.NET類庫(kù))苏携。Scala包括編譯器和類庫(kù),以及BSD許可證發(fā)布对粪。
學(xué)習(xí)Scala編程語(yǔ)言右冻,為后續(xù)學(xué)習(xí)Spark奠定基礎(chǔ)装蓬。
Scala安裝與配置
安裝
Scala需要Java運(yùn)行時(shí)庫(kù),安裝Scala需要首先安裝JVM虛擬機(jī)纱扭,推薦安裝JDK1.8乳蛾。
在http://www.scala-lang.org/ 下載Scala2.11.8程序安裝包
根據(jù)不同的操作系統(tǒng)選擇不同的安裝包,下載完成后肃叶,將安裝包解壓到安裝目錄岳锁。
注意:安裝時(shí)咆繁,安裝路徑中不能含有空格。
將scala安裝目錄下的bin目錄加入到PATH環(huán)境變量:
SCALA_HOME:
SCALA_HOME= D:\scala-2.11.8
在PATH變量中添加:
%SCALA_HOME%\bin
完成以上流程后镰吆,在命令行輸入:scala帘撰,進(jìn)入如下界面:
注意:該操作Windows和Linux配置流程是一樣的⊥蛎螅可以參考Java的JDK的配置過(guò)程摧找。
到此為止核行,Scala的安裝已經(jīng)成功。
配置IDEA
1) 打開IDEA工具蹬耘,如圖:點(diǎn)擊Confifigure
2) 點(diǎn)擊Plugins
2) 點(diǎn)擊Marketplace芝雪,搜索Scala,點(diǎn)擊Scala综苔,點(diǎn)擊Installed
3) 創(chuàng)建Maven項(xiàng)目
創(chuàng)建的maven項(xiàng)目默認(rèn)是不支持scala的惩系,需要為項(xiàng)目添加scala的framework,如圖:
在這里選擇Scala后如筛,在右邊的Use library中配置你的安裝目錄即可堡牡,最后點(diǎn)擊OK。
4) 在項(xiàng)目的目錄結(jié)構(gòu)中杨刨,創(chuàng)建scala文件夾晤柄,并標(biāo)記為source(fifile-project structure)
5) 以上配置都完成后,就可以在scala上點(diǎn)擊右鍵創(chuàng)建scala class了
Scala的運(yùn)行環(huán)境
REPL(Read Evaluate Print Loop):命令行
IDE:圖形開發(fā)工具
The Scala IDE (Based on Eclipse):http://scala-ide.org/
IntelliJ IDEA with Scala plugin:http://www.jetbrains.com/idea/download/
Netbeans IDE with the Scala plugin
Scala的常用數(shù)據(jù)類型
注意:在Scala中拭嫁,任何數(shù)據(jù)都是對(duì)象可免。例如:
在這里1是一個(gè)對(duì)象,所以可以使用toString方法做粤。
1. 數(shù)值類型:Byte浇借,Short,Int怕品,Long妇垢,F(xiàn)loat,Double
Byte: 8位有符號(hào)數(shù)字肉康,從-128 到 127
Short: 16位有符號(hào)數(shù)據(jù)闯估,從-32768 到 32767
Int: 32位有符號(hào)數(shù)據(jù)
Long: 64位有符號(hào)數(shù)據(jù)
scala> val a:Byte = 10
a: Byte = 10
scala> a+10
res6: Int = 20
#這里的res6是Scala自動(dòng)生成的變量的名字
scala> val b:Short = 20
b: Short = 20
scala> a+b
res7: Int = 30
注意:在Scala中,定義變量可以不指定類型吼和,因?yàn)镾cala會(huì)進(jìn)行類型的自動(dòng)推導(dǎo)涨薪。
2. 字符類型和字符串類型:Char和String
對(duì)于字符串,在Scala中可以進(jìn)行插值操作炫乓。
scala> val s1 = "Hello World"
s1: String = Hello World
scala> "My Name Is ${s1}"
res8: String = My Name Is ${s1}
scala> s"My Name Is ${s1}"
res9: String = My Name Is Hello World
注意:前面有個(gè)s刚夺;相當(dāng)于執(zhí)行:"My Name is " + s1,在Scala中${}方式使用變量必須在最前面添加標(biāo)識(shí)符s末捣。
3. Unit類型:相當(dāng)于Java中的void類型,就是沒有返回值侠姑。
scala> val f = ()
f: Unit = ()
小括號(hào)代表一個(gè)函數(shù),這個(gè)函數(shù)沒有返回值
Nothing 類型箩做,在執(zhí)行過(guò)程中莽红,產(chǎn)生Exception
scala> def myFunction = throw new Exception("Some Error")
myFunction: Nothing
函數(shù):
def 函數(shù)名 = 函數(shù)實(shí)現(xiàn)
Scala變量的申明和使用
使用val和var申明變量
scala> val answer = 8 * 3 + 2
answer: Int = 26
scala> answer+10
res10: Int = 36
可以在后續(xù)表達(dá)式中使用這些名稱
val:定義的值實(shí)際是一個(gè)常量
要申明其值可變的變量:var
scala> val a = 10
a: Int = 10
scala> a = 20
<console>:12: error: reassignment to val
a = 20
^
scala> var b = 10
b: Int = 10
scala> b = 20
b: Int = 20
注意:可以不用顯式指定變量的類型,Scala會(huì)進(jìn)行自動(dòng)的類型推到
Scala的函數(shù)和方法的使用
1. scala內(nèi)置函數(shù)邦邦,可以直接使用
scala> max(1,2)
<console>:12: error: not found: value max
max(1,2)
^
錯(cuò)誤原因安吁,沒有引入math包
scala> import scala.math._
import scala.math._
scala> max(1,2)
res9: Int = 2
說(shuō)明:
_ 相當(dāng)于Java中的*醉蚁,代表這個(gè)包下所有的東西。
res9: Int = 2
本質(zhì):定義了一個(gè)變量柳畔,res9馍管,保存執(zhí)行結(jié)果,推導(dǎo)出res9類型是Int薪韩。
scala> var a1 : Int = max(1,2)
a1: Int = 2
也可以省略類型聲明
scala> var a2 = max(2,3)
a2: Int = 3
2. 自定義函數(shù): 關(guān)鍵字 def
格式: def 函數(shù)名稱(參數(shù)列表 舉例 x : Int, y : Int) : 返回值類型 = {
函數(shù)實(shí)現(xiàn)
}
舉例:
1确沸、求和
scala> def sum(x:Int,y:Int) : Int = x + y
sum: (x: Int, y: Int)Int
scala> sum(10,20)
res10: Int = 30
scala> var a = sum(10 , 20)
a: Int = 30
2、求階乘 遞歸
scala> def myFactor(x:Int) : Int = {
| if (x <= 1)
| 1
| else
| x*myFactor(x-1)
| }
myFactor: (x: Int)Int
注意:沒有return語(yǔ)句俘陷。函數(shù)的最后一句話就是函數(shù)的返回值罗捎。
上面例子中,有函數(shù)的分支拉盾,1 和 x*myFactor(x-1) 都有可能是函數(shù)的最后一句話桨菜。
相當(dāng)于在前面都有return
scala> myFactor(5)
res11: Int = 120
3、求輸入的年份是否是閏年
普通閏年:能被4整除但不能被100整除的年份為普通閏年(如 2004年就是閏年捉偏,1999年不
是閏年)
世紀(jì)閏年:能被400整除的為世紀(jì)閏年(如 2000年就是世紀(jì)閏年 1900年不是世紀(jì)閏年)
scala> def isLeapYear(x:Int) = {
| if((x%4==0 && x%100 != 0) || x % 400 ==0) true
| else false
| }
isLeapYear: (x: Int)Boolean
scala> isLeapYear(2008)
res12: Boolean = true
scala> isLeapYear(2009)
res13: Boolean = false
Scala的條件表達(dá)式
Scala的if/else語(yǔ)法結(jié)構(gòu)和Java或C++一樣倒得。
不過(guò),在Scala中夭禽,if/else是表達(dá)式霞掺,有值,這個(gè)值就是跟在if或else之后的表達(dá)式的值讹躯。
Scala的循環(huán)
Scala擁有與Java和C++相同的while和do循環(huán)
Scala中菩彬,可以使用for和foreach進(jìn)行迭代
使用for循環(huán)案例:
scala> val list = List("Mary","Tom","Mike")
list: List[String] = List(Mary, Tom, Mike)
scala> for(s <- list) println(s)
Mary
Tom
Mike
scala> for(
| s <- list
| if(s.length > 3)
| ) println(s)
Mary
Mike
scala> for(s <- list if s.length <= 3) println(s)
Tom
注意:
(*) <- 表示Scala中的generator,即:提取符
(*)第三種寫法是第二種寫法的簡(jiǎn)寫
在for循環(huán)中潮梯,還可以使用yield關(guān)鍵字來(lái)產(chǎn)生一個(gè)新的集合
scala> val list = List("Mary","Tom","Mike")
list: List[String] = List(Mary, Tom, Mike)
scala> var newList = for{
| s <- list
| s1 = s.toUpperCase
| }yield(s1)
newList: List[String] = List(MARY, TOM, MIKE)
在上面的案例中骗灶,我們將list集合中的每個(gè)元素轉(zhuǎn)換成了大寫,并且使用yield關(guān)鍵字生成了一個(gè)新的集合秉馏。
使用while循環(huán):注意使用小括號(hào)耙旦,不是中括號(hào)
scala> var i = 0
i: Int = 0
scala> while(i < list.length){
| println(list(i))
| i += 1
| }
Mary
Tom
Mike
使用do ... while循環(huán)
scala> val list = List("Mary","Tom","Mike")
lsit: List[String] = List(Mary, Tom, Mike)
scala> var i = 0
i: Int = 0
scala> do{
| println(list(i))
| i += 1
| }while(i < list.length)
Mary
Tom
Mike
使用foreach進(jìn)行迭代
scala> val list = List("Mary","Tom","Mike")
lsit: List[String] = List(Mary, Tom, Mike)
scala> lsit.foreach(println)
Mary
Tom
Mike
注意:在上面的例子中,foreach接收了另一個(gè)函數(shù)(println)作為值
Scala函數(shù)的參數(shù)
Scala中萝究,有兩種函數(shù)參數(shù)的求值策略
Call By Value:對(duì)函數(shù)實(shí)參求值免都,且僅求一次
Call By Name:函數(shù)實(shí)參每次在函數(shù)體內(nèi)被用到時(shí)都會(huì)求值
scala> def test1(x:Int,y:Int) = x+x
test1: (x: Int, y: Int)Int
scala> test1(3+4,8)
res0: Int = 14
scala> def test2(x: =>Int,y: => Int )=x+x
test2: (x: => Int, y: => Int)Int
scala> test2(3+4,8)
res1: Int = 14
區(qū)別:
執(zhí)行過(guò)程對(duì)比:
test1 ---> test1(3+4,8) ---> test1(7,8) ---> 7+7=14
test2 ---> test2(3+4,8) ---> (3+4) + (3+4) ---> 7 + 7 = 14
scala> def bar(x:Int,y: => Int) : Int = 1
bar: (x: Int, y: => Int)Int
定義一個(gè)死循環(huán)
scala> def loop() : Int = loop
loop: ()Int
scala> bar(1,loop)
res4: Int = 1
scala> bar(loop,1)
解析:
1、y是call by name 糊肤,每次調(diào)用的時(shí)候,會(huì)被求值氓鄙。即函數(shù)中馆揉,如果用到y(tǒng),會(huì)被求值抖拦。但是函數(shù)定
義中升酣,沒有用到y(tǒng)舷暮,所以不會(huì)被求值。
2噩茄、x是call by value 下面,對(duì)函數(shù)參數(shù)求值,并且只求一次绩聘。即不管用不用得到沥割,x都會(huì)被求值。調(diào)用
loop 產(chǎn)生死循環(huán)凿菩。
Scala中的函數(shù)參數(shù)
默認(rèn)參數(shù)
當(dāng)你沒有給參數(shù)賦值的時(shí)候机杜,就使用默認(rèn)值
scala> def fun1(name:String) : String = "Hello " + name
fun1: (name: String)String
scala> fun1("Tom")
res0: String = Hello Tom
scala> fun1()
<console>:13: error: not enough arguments for method fun1: (name:
String)String.
Unspecified value parameter name.
fun1()
^
scala> def fun1(name:String="Andy") : String = "Hello " + name
fun1: (name: String)String
scala> fun1("Tom")
res2: String = Hello Tom
scala> fun1()
res3: String = Hello Andy
代名參數(shù)
當(dāng)有多個(gè)默認(rèn)參數(shù)的時(shí)候,通過(guò)代名參數(shù)可以確定給哪個(gè)參數(shù)賦值
scala> def fun2(str:String="Good Morning ",name:String=" Tom
",age:Int=20)=str + name + " and the age of " + name + " is" + age
fun2: (str: String, name: String, age: Int)String
scala> fun2()
res4: String = Good Morning Tom and the age of Tom is20
scala> fun2(name= " Mary ")
res5: String = Good Morning Mary and the age of Mary is20
可變參數(shù)
類似于java中的可變參數(shù)衅谷。即 參數(shù)數(shù)量不固定椒拗。
舉例:求多個(gè)數(shù)字的和:
def sum(x:Int,y:Int) = x+y
def sum(x:Int,y:Int,z:Int) = x+y+z
def sum(args:Int*) = {
var result = 0
for(x <- args) result += x
result
}
scala> def sum(args:Int*) = {
| var result = 0
| for(x <- args) result += x
| result
| }
sum: (args: Int*)Int
scala> sum(1,2,3)
res6: Int = 6
scala> sum(2,3)
res7: Int = 5
Scala的Lazy值(懶值)
鋪墊:Spark 核心 RDD (數(shù)據(jù)集合) 。操作數(shù)據(jù)集合中的數(shù)據(jù)時(shí)获黔,我們使用算子(函數(shù)蚀苛、方法)。
算子有兩種:
1玷氏、Transformation : 延時(shí)計(jì)算堵未,不會(huì)立刻觸發(fā)計(jì)算 T
2、Action : 觸發(fā)計(jì)算 A
RDD.T.T.T.T.A
Transformation 用了 lazy值
定義:當(dāng)val被申明為lazy時(shí)预茄,它的初始化將被推遲兴溜,直到我們首次對(duì)它取值
scala> val x : Int = 10
x: Int = 10
scala> val y : Int = x + 1
y: Int = 11
定義后會(huì)立即觸發(fā)計(jì)算
scala> lazy val z : Int = x + 1
z: Int = <lazy>
初始化會(huì)被延遲,沒有觸發(fā)計(jì)算耻陕。當(dāng)我們第一次使用z的時(shí)候拙徽,才會(huì)觸發(fā)計(jì)算
scala> z
res9: Int = 11
舉例:讀文件
(1)讀一個(gè)存在的文件
scala> val words =
scala.io.Source.fromFile("D:\\testdata\\scala\\student.txt").mkString
words: String =
1 Tom 12
2 Mary 13
3 Lily 15
scala> lazy val words =
scala.io.Source.fromFile("D:\\testdata\\scala\\student.txt").mkString
words: String = <lazy>
scala> words
res10: String =
1 Tom 12
2 Mary 13
3 Lily 15
(2)讀不存在的文件
scala> val words =
scala.io.Source.fromFile("D:\\testdata\\scala\\studkjslfkdjlskdjfldent.txt").mkS
tring
java.io.FileNotFoundException: H:\tmp_files\studkjslfkdjlskdjfldent.txt (系統(tǒng)找不
到指定的文件。)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at scala.io.Source$.fromFile(Source.scala:91)
at scala.io.Source$.fromFile(Source.scala:76)
at scala.io.Source$.fromFile(Source.scala:54)
... 32 elided
scala> lazy val words =
scala.io.Source.fromFile("D:\\testdata\\scala\\odsfsfisnt.txt").mkString
words: String = <lazy>
scala> words
java.io.FileNotFoundException: H:\tmp_files\stude932409230ijdosijf;oisnt.txt (系
統(tǒng)找不到指定的文件诗宣。)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at scala.io.Source$.fromFile(Source.scala:91)
at scala.io.Source$.fromFile(Source.scala:76)
at scala.io.Source$.fromFile(Source.scala:54)
at .words$lzycompute(<console>:11)
at .words(<console>:11)
... 32 elided
異常的處理
Scala異常的工作機(jī)制和Java或者C++一樣膘怕。直接使用throw關(guān)鍵字拋出異常。
Scala中的數(shù)組
Scala數(shù)組的類型:
定長(zhǎng)數(shù)組:使用關(guān)鍵字Array
scala> val a = new Array[Int](10)
a: Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
scala> val a = new Array[String](10)
a: Array[String] = Array(null, null, null, null, null, null, null,
null, null, null)
scala> val a = Array("Tom","Andy","Lily")
a: Array[String] = Array(Tom, Andy, Lily)
scala> val a = Array("Tom","Andy","Lily",1)
a: Array[Any] = Array(Tom, Andy, Lily, 1)
scala> val a : Array[String] = Array("Tom","Andy","Lily",1)
<console>:11: error: type mismatch;
found : Int(1)
required: String
val a : Array[String] = Array("Tom","Andy","Lily",1)
變長(zhǎng)數(shù)組:使用關(guān)鍵字ArrayBuffffer
scala> import scala.collection.mutable._
import scala.collection.mutable._
scala> val a = ArrayBuffer[Int]()
a: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()
scala> a
res13: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()
scala> a += 1
res14: a.type = ArrayBuffer(1)
scala> a += 2
res15: a.type = ArrayBuffer(1, 2)
scala> a += 10
res16: a.type = ArrayBuffer(1, 2, 10)
scala> a += (100,200,300)
res17: a.type = ArrayBuffer(1, 2, 10, 100, 200, 300)
scala> a.
++ combinations groupBy mapResult
reverse to
++: companion grouped max
reverseIterator toArray
++= compose hasDefiniteSize maxBy
reverseMap toBuffer
++=: contains hashCode min
runWith toIndexedSeq
+: containsSlice head minBy
sameElements toIterable
+= copyToArray headOption mkString
scan toIterator
+=: copyToBuffer indexOf nonEmpty
scanLeft toList
- corresponds indexOfSlice orElse
scanRight toMap
-- count indexWhere padTo
segmentLength toSeq
--= diff indices par
seq toSet
-= distinct init partition
size toStream
/: drop inits patch
sizeHint toString
:+ dropRight insert permutations
sizeHintBounded toTraversable g
:\ dropWhile insertAll prefixLength
slice toVector
<< endsWith intersect prepend
sliding transform
WithFilter equals isDefinedAt prependAll
sortBy transpose
addString exists isEmpty product
sortWith trimEnd
aggregate filter isTraversableAgain readOnly
sorted trimStart
andThen filterNot iterator reduce
span union
append find last reduceLeft
splitAt unzip
appendAll flatMap lastIndexOf reduceLeftOption
startsWith unzip3
apply flatten lastIndexOfSlice reduceOption
stringPrefix update
applyOrElse fold lastIndexWhere reduceRight
sum updated
canEqual foldLeft lastOption reduceRightOption
tail view
clear foldRight length reduceToSize
tails withFilter
clone forall lengthCompare remove
take zip
collect foreach lift repr
takeRight zipAll
collectFirst genericBuilder map result
takeWhile zipWithIndex
去掉最后兩個(gè)元素
scala> a.trimEnd(2)
scala> a
res19: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2,
10, 100)
遍歷數(shù)組
scala> val a = Array("Tom","Andy","Lily")
a: Array[String] = Array(Tom, Andy, Lily)
scala> for(s <- a) println(s)
Tom
Andy
Lily
scala> a.foreach(println)
Tom
Andy
Lily
Scala數(shù)組的常用操作
scala> val myarray = Array(1,2,7,8,10,3,6)
myarray: Array[Int] = Array(1, 2, 7, 8, 10, 3, 6)
scala> myarray.max
res22: Int = 10
scala> myarray.min
res23: Int = 1
scala> myarray.sortWith(_>_)
res24: Array[Int] = Array(10, 8, 7, 6, 3, 2, 1)
scala> myarray.sortWith(_<_)
res25: Array[Int] = Array(1, 2, 3, 6, 7, 8, 10)
解釋 myarray.sortWith(_>_)
sortWith(以某種 規(guī)則 進(jìn)行排序)
完整:myarray.sortWith((a,b) => {if(a>b) true else false})
(a,b) => {if(a>b) true else false} 是一個(gè)函數(shù)召庞。匿名函數(shù):沒有名字 傳入兩個(gè)參數(shù)
a b 返回值 bool岛心。
(a,b) => {if(a>b) true else false} 簡(jiǎn)寫 _>_
匿名函數(shù)作為sortWith的參數(shù) 高級(jí)函數(shù)(函數(shù)式編程)
Scala的多維數(shù)組
(1)和Java一樣,通過(guò)數(shù)組的數(shù)組來(lái)實(shí)現(xiàn)
定義一個(gè)固定長(zhǎng)度的二維數(shù)組
scala> val matrix = Array.ofDim[Int](3,4)
matrix: Array[Array[Int]] = Array(
Array(0, 0, 0, 0),
Array(0, 0, 0, 0),
Array(0, 0, 0, 0))
scala> matrix(1)(2) = 10
scala> matrix
res27: Array[Array[Int]] = Array(
Array(0, 0, 0, 0),
Array(0, 0, 10, 0),
Array(0, 0, 0, 0))
(2)定義一個(gè)二維數(shù)組篮灼,其中每個(gè)元素是一個(gè)一維數(shù)組忘古,但是其長(zhǎng)度不固定
scala> val triangle = new Array[Array[Int]](10)
triangle: Array[Array[Int]] = Array(null, null, null, null, null, null,
null, null, null, null)
scala> for( i <- 0 until triangle.length)
| triangle(i) = new Array[Int](i+1)
scala> triangle
res29: Array[Array[Int]] = Array(
Array(0),
Array(0, 0),
Array(0, 0, 0),
Array(0, 0, 0, 0),
Array(0, 0, 0, 0, 0),
Array(0, 0, 0, 0, 0, 0),
Array(0, 0, 0, 0, 0, 0, 0),
Array(0, 0, 0, 0, 0, 0, 0, 0),
Array(0, 0, 0, 0, 0, 0, 0, 0, 0),
Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
映射
映射就是Map集合,由一個(gè)(key,value)組成诅诱。
-> 操作符用來(lái)創(chuàng)建
創(chuàng)建一個(gè)Map來(lái)保存學(xué)生的成績(jī)
scala> val scores = Map("Tom" -> 80, "Andy" -> 85, "Mike" -> 82)
scores: scala.collection.immutable.Map[String,Int] = Map(Tom -> 80, Andy -> 85,
Mike -> 82)
說(shuō)明:
Map[String,Int] key是String value是Int
scala中髓堪,映射是有兩種,一種是可變的,一種是不可變的
scala.collection.immutable 不可變Map
scala.collection.mutable 可變
scala> val scores = scala.collection.mutable.Map("Tom" -> 80, "Andy" -> 85,
"Mike" -> 82)
scores: scala.collection.mutable.Map[String,Int] = Map(Mike -> 82, Tom -> 80,
Andy -> 85)
scala> val scores = scala.collection.mutable.Map(("Tom",80),("Andy",85),
("Mike",82))
scores: scala.collection.mutable.Map[String,Int] = Map(Mike -> 82, Tom -> 80,
Andy -> 85)
映射的操作:
1干旁、獲取映射中的值
scala> scores("Tom")
res0: Int = 80
scala> scores.get("Andy")
res1: Option[Int] = Some(85)
scala> scores.get("Anddskfjlskjdfly")
res2: Option[Int] = None
get方法不會(huì)報(bào)錯(cuò)驶沼,直接取值會(huì)報(bào)錯(cuò)
scala> scores("sldfkjlskdjflksd")
java.util.NoSuchElementException: key not found: sldfkjlskdjflksd
at scala.collection.MapLike$class.default(MapLike.scala:228)
at scala.collection.AbstractMap.default(Map.scala:59)
at scala.collection.mutable.HashMap.apply(HashMap.scala:65)
... 32 elided
scala> scores.contains("Tom")
res4: Boolean = true
scala> scores.contains("Todfkjlskdjflksjdm")
res5: Boolean = false
如果取到Tom,則返回争群。未取到回怜,則返回-1。
scala> scores.getOrElse("Tom",-1)
res6: Int = 80
scala> scores.getOrElse("Tosldkfjlskdjflksdjflm",-1)
res7: Int = -1
2换薄、更新映射中的值
注意:必須操作是可變映射
scala> scores
res8: scala.collection.mutable.Map[String,Int] = Map(Mike -> 82, Tom -> 80,
Andy -> 85)
scala> scores("Andy")
res9: Int = 85
scala> scores("Andy") = 90
scala> scores
res11: scala.collection.mutable.Map[String,Int] = Map(Mike -> 82, Tom -> 80,
Andy -> 90)
3玉雾、映射的遍歷
使用foreach
scala> for(s <- scores) println(s)
(Mike,82)
(Tom,80)
(Andy,90)
scala> scores.foreach(println)
(Mike,82)
(Tom,80)
(Andy,90)
mutable 是 可變的
val 是不可變的
兩者是否沖突?
不沖突
scala> val scores =scala.collection.mutable.Map("Tom" -> 80, "Andy" -> 85,
"Mike" -> 82)
scores: scala.collection.mutable.Map[String,Int] = Map(Mike -> 82, Tom -> 80,
Andy -> 85)
scala> scores
scores scores1
scala> scores("Tom")
res6: Int = 80
scala> scores("Tom") = 90
scala> scores("Tom")
res8: Int = 90
scala> scores
scores scores1
scala> scores
res9: scala.collection.mutable.Map[String,Int] = Map(Mike -> 82, Tom -> 90, Andy
-> 85)
scala> scores = Map("Tom" -> 80, "Andy" -> 85, "Mike" -> 82)
<console>:13: error: reassignment to val
scores = Map("Tom" -> 80, "Andy" -> 85, "Mike" -> 82)
^
元組(Tuple)
元組是不同類型的值的聚集专控。
例如:val t = (1, 3.14, "Fred") // 類型為Tuple3[Int, Double, java.lang.String]
這里:Tuple是類型抹凳,3是表示元組中有三個(gè)元素。
Scala中的Tuple:是不同類型值的集合
(Tom,80)
(Andy,90)
mutable 是 可變的
val 是不可變的
兩者是否沖突伦腐?
不沖突
scala> val scores =scala.collection.mutable.Map("Tom" -> 80, "Andy" -> 85,
"Mike" -> 82)
scores: scala.collection.mutable.Map[String,Int] = Map(Mike -> 82, Tom -> 80,
Andy -> 85)
scala> scores
scores scores1
scala> scores("Tom")
res6: Int = 80
scala> scores("Tom") = 90
scala> scores("Tom")
res8: Int = 90
scala> scores
scores scores1
scala> scores
res9: scala.collection.mutable.Map[String,Int] = Map(Mike -> 82, Tom -> 90, Andy
-> 85)
scala> scores = Map("Tom" -> 80, "Andy" -> 85, "Mike" -> 82)
<console>:13: error: reassignment to val
scores = Map("Tom" -> 80, "Andy" -> 85, "Mike" -> 82)
^
scala> val t1 = Tuple(1,0.32,"Hello")
<console>:17: error: not found: value Tuple
val t1 = Tuple(1,0.32,"Hello")
^
scala> val t1 = Tuple3(1,0.32,"Hello")
t1: (Int, Double, String) = (1,0.32,Hello)
scala> val t1 = (1,0.32,"Hello")
t1: (Int, Double, String) = (1,0.32,Hello)
scala> val t1 = (1,0.32,"Hello",1,2,3,10)
t1: (Int, Double, String, Int, Int, Int, Int) = (1,0.32,Hello,1,2,3,10)
scala> t1.
_1 _3 _5 _7 copy hashCode productElement
productPrefix
_2 _4 _6 canEqual equals productArity productIterator toString
scala> t1._1
res30: Int = 1
scala> t1._3
res31: String = Hello
如何遍歷Tuple中的元素
注意:Tuple沒有提供foreach函數(shù)赢底,我們使用productIterator
遍歷Tuple分成兩步:
1、使用productIterator生成迭代器
2柏蘑、遍歷
scala> t1.productIterator.
++ corresponds foldRight max reduceLeft
span toSeq
/: count forall maxBy
reduceLeftOption sum toSet
:\ drop foreach min
reduceOption take toStream
GroupedIterator dropWhile grouped minBy reduceRight
takeWhile toString
addString duplicate hasDefiniteSize mkString
reduceRightOption to toTraversable
aggregate exists hasNext next
sameElements toArray toVector
buffered filter indexOf nonEmpty scanLeft
toBuffer withFilter
collect filterNot indexWhere padTo scanRight
toIndexedSeq zip
collectFirst find isEmpty partition seq
toIterable zipAll
contains flatMap isTraversableAgain patch size
toIterator zipWithIndex
copyToArray fold length product slice
toList
copyToBuffer foldLeft map reduce sliding
toMap
scala> t1.productIterator.foreach(println)
1
0.32
Hello
1
2
3
10
scala中的文件操作
類似于Java IO
舉例:
1幸冻、讀取文件
2、讀取二進(jìn)制文件
3咳焚、從url中獲取信息
4洽损、寫入文件
5、scala調(diào)用java類庫(kù)
/**
* Created by root on 2019/10/19.
*
* scala 讀取文件樣例
*/
import java.io.{File, FileInputStream, PrintWriter}
import scala.io.Source._
object TestIO {
def main(args: Array[String]): Unit = {
//讀取行
lazy val sourse = fromFile("H:\\tmp_files\\student.txt")
println("-------mkString-----------")
// println(sourse.mkString)
println("-------lines-----------")
// val lines = sourse.getLines()
// lines.foreach(println)
//讀取字符
// for (c <- sourse) println(c)
//從url或者其他數(shù)據(jù)源讀取 http://www.baidu.com
println("-------fromURL-----------")
// var source2 = fromURL("http://www.baidu.com","UTF-8")
// println(source2.mkString)
println("-------Read Bytes-----------")
var file = new File("H:\\tmp_files\\hudson.war")
//構(gòu)建inputstream
var in = new FileInputStream(file)
//構(gòu)建buffer
val buffer = new Array[Byte](file.length().toInt)
//讀取
in.read(buffer)
println(buffer.length)
//關(guān)閉
in.close()
//寫入文本文件
println("-------Write File-----------")
var out = new PrintWriter("H:\\tmp_files\\insert1019.txt")
for ( i <- 0 until 10) out.println(i)
out.close()
}
}