Scala学习(一) 快速入门

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Fei20140908/article/details/79217188

学习Spark就要学习Scala,今天开始快速学习Scala.直接在这里做笔记了.

1 Scala基础与语法

1.1 基本数据类型

8中常见数据类型:Byte,Char,Short,Int,Long,Float,DoubleBoolean. 这里的FloatDouble 的具体区别就是 :

浮点数如0.0f或者0.0F,若没有 f 后缀则是Double变量

String也是基本数据类型,它属于java.lang 包,这个包是默认导入的.

1.2 Scala变量声明

Scala通过 varval 来声明变量.其中 var 是可以重新赋值的,和普通变量没啥区别,但是val 赋值一次后不能再赋值,相当于java中的final修饰的变量.

举个栗子,以val 为例,var 差不多

scala> val i=10
i: Int =10 
scala>println(i)
10
scala>i=11  //i是不可变的,所以会报错
<console>:8:error reassignment to val
    i=10
     ^
scala> val a,b = 1f //scala允许一次定义多个变量,这里定义两个Float类型的
a:Int = 10
b:Int = 10

//在定义的时候可以指定数据类型
scala> val i:Int =10
i:Int = 10

1.3 算术操作符介绍

这个和c或者java没区别,直接上例子

//算术运算符=-*/
scala> 1+2 //在scala中+-*/也是对象的函数,所以也可以这么调用1.+(2)
res0:Int=3

//关系运算符== > >= ...
scala>3==2
res1:Boolean = false

//逻辑运算符 && || ! 
scala> true&&false
res2:Boolean:false

//位运算符 & | ^ (与/或/异或)
scala> 0^1
res3:1

//赋值运算符 += -= <<= ...
//总的来说就是 A op B ==> A= A op B
scala>var a=3
a:Int=3
scala>a+=2
5 

1.4 条件语句

scala中的条件语句是有返回值的,可以将其赋值给某个变量,类似于三目运算符.

if(条件) x else y

当然也可以给x ,y加上花括号

if (条件) {
...
}else {
...
}

举个例子

scala> val i=if(3>1) 3 else 1
i:Int=3 //3赋值给了变量i

scala>if(x<20){
|   println("This is if test")
|}
This is if test

scala中的条件语句在for循环中或match 模式匹配中可以成为 守卫 看下面讲循环的例子.

1.5 循环

与java c一样的循环结构 for ,while,do-while等,但是具体写起来还是有差别的

1.5.1 for 循环

for (var <- set)
{
...
}

举个例子

scala>for(i<- 1 to 10) print(i+" ") //1 to 10 生成Range(1,2,..,10)
1 2 3 4 5 6 7 8 9 10

//1 until 10 生成的不包含尾部,生成的是(1,2,...,9)
scala>for(i<- 1 until 10) print(i+" ")
1 2 3 4 5 6 7 8 9

//for 循环中使用守卫
scala>for(i<- 1 to 10 if i%2==0)print(i+" ")
2 4 6 8 10
scala>for(i<- 1 to 10 if i%2==0;if i!=2)print(i+" ") //多个过滤条件用分号隔开.
4 6 8 10

for 循环中使用守卫


scala>for(i<- 1 to 10 if i%2==0)print(i+" ")
2 4 6 8 10
scala>for(i<- 1 to 10 if i%2==0;if i!=2)print(i+" ") //多个过滤条件用分号隔开.
4 6 8 10

for循环嵌套,这里和一般的java中的嵌套不一样.

scala>for(i<- 1 to 5;j<- 1 to 5 if i%2==0)print(i*j+" ")
2 3 4 6 8 10 12 16 20 

利用yield关键字返回一个新集合

scala>val v1 = for(i<- 1 to 5)yield i
v1:Scala.collection.immutable.IndexSeq[Int]= Vector(1,2,3,4,5)

1.5.2 while 循环

while(条件表达式){
...
}

直接上例子

scala> while(i<=5){
     | i +=1
     | print(i+ " ")
     | }
2 3 4 5 6 

注意的是,在forwhile中都没有用到breakcontinue,这是因为在scala中没有break和continue两个关键字,continue可以通过if条件语句来控制是否要向下执行,而break语句在scala中有特殊的实现

import scala.util.control.Breaks._
import scala.util.Random
object ControlStatementBreak{
    def main(args:Array[String]){
        breakable{
        while(true){
            val r = new Random()
            val i= r.nextInt(10)
            println("i=="+i)
            if(i==5){
            break
            }
        }
    }
}
}
/*这段代码首先import 了 scala.util.control.Breaks._ ,这样就可以使用
breakable和break语句了.在while语句外面用breakable语句块包围了,然后在需
要break的地方调用break方法,这里的break 不是关键字,而是一个scala方法,这个
方法会抛出异常从而中断循环
*/

1.5.3 do-while 循环

这个和while类似,和java中do-while和while的循环的区别一样,所以不再赘述.
语法:

do{
循环体
}(条件表达式)

严格的来说, scala中的for被成为表达式,它和if一样,可以返回结果,而while或者do-while类型的就是循环结构,它们返回的结构为Unit类型.

1.6 异常控制

分为捕获异常和抛出异常

1.6.1 抛出异常使用关键字 throw

例如

throw new IlleagalArgumentException

1.6.2 捕获异常

例如:

try{
...
} catch {
    case ex:NullPointException=>...
    case ...
}
finally{//finally语句不一定会有,如果有一定会执行
    println("通常用来释放资源")
}

举个例子(文件读取)

object ReadFileTest{
    def main(args:Array[String]){
    try{
        val file=Source.fromFile("F://2.txt")
        val lines=file.getLines()
        for(content<- lines){
        println(content)
        }
    }catch{
    case ex:FileNotFoundException=>println("输入的文件不存在"+ex)
    case ex:Exception=> println(ex)
    }finally{
    println("通常用来释放资源")
    }
}
}

2. Scala 中Array\Map等数据结构

2.1 定长数组和可变数组

默认情况下是定长数组,若定义可变数组,需要显示导入包

import scala.collection.mutable.ArrayBuffer

定义长度为2 的字符串数组

scala> val arrStr =Array("Scala","Spark")
arrStr: Array[String] = Array(Scala, Spark)

定义长度为3的整数类型数组,初始值为0

scala> import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.ArrayBuffer

scala> val arrBufInt=ArrayBuffer[Int]()
arrBufInt: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()

2.2 数组常用算法

scala> arrStr(0)="Storm" //直接赋值

scala> arrStr.mkString(",")//指定分隔符
res4: String = Storm,Spark

//将定长数组变成变长数组
scala> arrStr.toBuffer
res6: scala.collection.mutable.Buffer[String] = ArrayBuffer(Storm, Spark)

//数组遍历
scala> for(i<- 0 until arrStr.length)println(arrStr(i)) 
Storm
Spark
//或者 类似与java中的增强for
scala> for(elem<- arrStr)println(elem)
Storm
Spark

可变数组特有操作

scala> arrBufInt+=1 //用+=在尾端添加元素
res10: arrBufInt.type = ArrayBuffer(1)

scala> arrBufInt+=(2,3,4,5) //同时添加多个元素
res11: arrBufInt.type = ArrayBuffer(1, 2, 3, 4, 5)

//用++= 可以直接追加一个集合

scala> arrBufInt++=arrBufInt //将自己追加给自己
res13: arrBufInt.type = ArrayBuffer(1, 2, 3, 4, 5, 1, 2, 3, 4, 5)

scala> arrBufInt++=Array(6,7,8)//追加个定长数组
res14: arrBufInt.type = ArrayBuffer(1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 6, 7, 8)

//移除数组的最后2个元素
scala> arrBufInt.trimEnd(2)
scala> arrBufInt
res16: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 6)

//移除数组的第三个元素
scala> arrBufInt.remove(2)
res17: Int = 3

//在下标为2的位置开始移除4 个元素
scala> arrBufInt.remove(2,4)
scala> arrBufInt
res19: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4, 5, 6)

//将变长数组转换为定长数组
scala> val arr=arrBufInt.toArray
arr: Array[Int] = Array(1, 2, 3, 4, 5, 6)

2.3 Map映射

默认情况下scala中使用不可变的映射,可变映射必须导入scala.collection.mutable.Map

定义映射:

val mapCase=Map("china"->"beijing","france"->"paris")
scala>val bigData=Map("scala"->35,"hadoop"->30,"spark"->50)
bigData:Scala.collection.immutable.Map[String,Int]=Map(scala->35,hadoop ->30,spark->50)
//获取key为scala的值
scala>bigData("scala")
res0:Int=35
scala>bigData.contains("hadoop") //判断是否有key为hadoop的键值对
res1:Boolean=true
scala>bigData.getOrElse("spark",70) //若映射中存在包含key为spark的键值
//对,如果有就返回对应的值,否则返回70
res2:Int=50
//添加分隔符
scala>bigData.mkString("{",",","}")
res3:Strin{scala->35,hadoop->30,spark->50)
scala>bigData.drop(2) //以下标0开始,返回角标为2的元素
Map(spark->50)
res4:scala.collection.immutable.Map[String,Int]=Map(Spark->50)

构建可变映射

scala> import scala.collection.mutable.Map
import scala.collection.mutable.Map

scala> val bigDataVar=Map("scala"->35,"hadoop"->30,"spark"->50)
bigDataVar: scala.collection.mutable.Map[String,Int] = Map(spark -> 50, hadoop -> 30, scala -> 35)

scala> bigDataVar("spark")
res0: Int = 50

scala> bigDataVar("spark")=100//直接赋值

scala> bigDataVar("spark")
res2: Int = 100

scala> bigDataVar+=("kafka"->69) //在后面添加键值对
res3: bigDataVar.type = Map(spark -> 100, hadoop -> 30, scala -> 35, kafka -> 69)

scala> bigDataVar -=("kafka"->69) //删除键值对,书上这个代码是错的
<console>:14: error: type mismatch;
 found   : (String, Int)
 required: String
       bigDataVar -=("kafka"->69)
                            ^

scala> bigDataVar -=("kafka") //这么写就对了
res6: bigDataVar.type = Map(spark -> 100, hadoop -> 30, scala -> 35)

//遍历映射
scala> for((k,v)<-bigDataVar)println(k+" "+v) 
spark 100
hadoop 30
scala 35
//只打印key
scala> for(k<-bigDataVar.keySet)println(k)
spark
hadoop
scala

2.4 Tuple元组

元组和数组很像,但是它能包含不同种类型的数据


scala> val tuple1=(1,2,4,5,"hello")
tuple1: (Int, Int, Int, Int, String) = (1,2,4,5,hello)
scala> println(tuple1._1) //打印tuple中的元素
1

2.5 List 列表

和数组很想,数据类型也都必须保持一致,但是区别如下

  • 列表中元素不可变
  • 列表表示一个链表
//定义一个列表
scala> val fruit:List[String]=List("apples","oranges","pears")
fruit: List[String] = List(apples, oranges, pears)

scala> val nums:List[Int]=List(1,2,4,4)
nums: List[Int] = List(1, 2, 4, 4)
//定义个空列表

scala> val empty:List[Nothing]=List()
empty: List[Nothing] = List()
//定义二维列表
scala> val dim:List[List[Int]]=
     | List(
     | List(1,2,3),
     | List(4,5,6),
     | List(7,8,9)
     | )
dim: List[List[Int]] = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9))

定义列表的另一种方式
可以用一个无尾 Nil:: ,相当于c语言中的’null’和’->’

scala>val fruit="apples"::("oranges"::("pears"::Nil))
fruit:List[String]=List(apples,oranges,pears)
//定义一个空列表
scala>val empty=Nil
//定义二维列表
scala>val dim=(1::(2::(3::Nil)))::(4::(5::(6::Nil)))::(7::(8::(9::Nil)))::Nil
dim:List[List[Int]]=List(List(1,2,3),List(4,5,6),List(7,8,9))

列表基本操作

scala> class Test{
     | def ops{
     | val fruit= "apples"::("oranges"::("pears"::Nil))
     | val nums =Nil
     | println("Head of fruit "+fruit.head)//head是集合中的第一个元素
     | println("Tail of fruit "+fruit.tail) //tail是除了第一个元素外的所有元素的集合
     | println("Check if fruit is empty "+fruit.isEmpty)
     | println("Chek if nums  is empty "+nums.isEmpty)
     | }
     | }
defined class Test

scala> val t= new Test
t: Test = Test@51684c4e

scala> t.ops
Head of fruit apples
Tail of fruit List(oranges, pears)
Check if fruit is empty false
Chek if nums  is empty true

串联列表
串联列表有三种方法
1. 使用:::
2. 使用 List.:::()
3. 使用 List.concat(list1,list2)

//定义两个list
scala> val fruit1="apples"::Nil
fruit1: List[String] = List(apples)

scala> val fruit2="orange"::Nil
fruit2: List[String] = List(orange)
//使用方法1
scala> var temp =fruit1:::fruit2
temp: List[String] = List(apples, orange)
//使用方法 2
scala> temp = fruit1.:::(fruit2)
temp: List[String] = List(orange, apples)
//使用方法3
scala> temp=List.concat(fruit1,fruit2)
temp: List[String] = List(apples, orange)

2.7 set集合

set集合同样也有可变不可变 ,可变导入scala.collection.mutable.Set
它的操作放发与list很像,直接上例子

scala> var s:Set[Int]=Set() //定义一个set
s: Set[Int] = Set()

scala> var s :Set[Int]=Set(1,3,4,5)
s: Set[Int] = Set(1, 3, 4, 5)

scala> var s =Set(1,3,4,5)
s: scala.collection.immutable.Set[Int] = Set(1, 3, 4, 5)
// 这里展示基本操作

scala> val book=Set("scala","spark","hadoop")
book: scala.collection.immutable.Set[String] = Set(scala, spark, hadoop)

scala> println("Head of book " + book.head) //与List的head和tail一样
Head of book scala

scala> println("tail of book "+book.tail)
tail of book Set(spark, hadoop)

scala> book.isEmpty
res2: Boolean = false

其它的集合方法大全的话,这里就不列了,可以参考后文中的官方链接

2.7 scala官方文档链接

scala中文文档官方链接


参考文献

这里参考书籍是《Spark零基础实战》,作者王家林和孔祥瑞.大部分代码都是敲过在本机上运行成功的.

猜你喜欢

转载自blog.csdn.net/Fei20140908/article/details/79217188