Scala基础
一、 IntelliJ IDEA集成Scala插件
在plugin中搜索Scala插件
二、 下载Scala
三、 新建Scala项目(使用SBT)(暂时还没使用到。。。)
注意Scala的版本和spark的版本:
spark1.6.0 对应 scala2.10
spark2.0.0 对应 scala2.11
四、 新建Scala项目(普通项目类似eclipse的java项目)
五、 声明变量
object VariableDemo {
def main(args:Array[String]) {
//使用val定义的变量值是不可变的,相当于java里用final修饰的变量
val i = 1
//使用var的变量是可变得,在Scala中鼓励使用val
var s = "hello"
print(i)
print(s)
}
}

六、 常用类型
Scala和Java一样,有7种数值类型Byte、Char、Short、Int、Long、Float和Double(无包装类型)和一个Boolean类型
七、 条件表达式
object ConditionDemo {
def main(args: Array[String]) {
val x = 1
//判断x的值,将结果赋值给y
val y = if (x > 0) 1 else -1
println(y) //1
//混合类型表达式
val z = if (x > 1) 1 else " error "
println(z) //error
//如果缺失else 相当于if(x > 2) 1 else ()
val m = if (x > 2) 1
println(m) //()
//在scala中每个表达式都有值,scala中有个Unit类,写做(),相当于Java中的void
val n = if (x > 2) 1 else ()
println(n) //()
//if 和 else if
val k = if (x < 0) 0
else if (x >= 1) 1
else -1
println(k) //1
}
}

八、 块表达式
object BlockExpressionDemo {
def main(args: Array[String]) {
val x = 0
//在scala中{}包含一系列表达式,块中最后一个表达式的值就是块的值
val result = {
if (x < 0 ){
-1
}else if(x >= 1){
1
}else{
"error"
}
}
//result的值就是块表达式的结果
println(result) //error
}
}

九、 循环
在scala中有for循环和while循环,用for循环比较多
for循环语法结构:for (i <- 表达式/数组/集合)
object ForDemo {
def main(args: Array[String]) {
//for(i <- 表达式),表达式1 to 10返回一个Range(区间)
//每次循环将区间中的一个值赋给i
for (i <- 1 to 10){
println(i) //1,2,3,4,5,6,7,8,9,10
}
//for(i <- 数组)
val arr = Array("a","b","c")
for (i <- arr){
println(i) //a,b,c
}
//高级for循环
//每个生成器都可以带一个条件,注意:if前面没有分号
for (i <- 1 to 3 ; j <- 1 to 3 if i != j)
print((10 * i + j) + " ") //12 13 21 23 31 32
println()
//for推导式:如果for循环的循环体以yield开始,则该循环会构建出一个集合
//每次迭代生成集合中的一个值
val v = for (i <- 1 to 10 )yield i * 10
println(v) //Vector(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
}
}
十、 定义方法和函数
十一、 定义数组
1. 定长数组

2. 变长数组

3. 数组代码:
object ArrayDemo { def main(args: Array[String]) { //初始化一个长度为8的定长数组,所有元素为0 val arr1 = new Array[Int](8) //直接打印定长数组,内容为数组的hashcode值 println(arr1) //[I@3c5a99da //将数组转换成数组缓冲,可以看到原数组中的内容 println(arr1.toBuffer) //ArrayBuffer(0, 0, 0, 0, 0, 0, 0, 0) //注意:如果new,相当于调用了数组的apply方法,直接为数组赋值 //初始化一个长度为1的定长数组 值为10 val arr2 = Array[Int](10) println(arr2.toBuffer) //ArrayBuffer(10) //定义一个长度为3的定长数组 val arr3 = Array("hadoop","storm","spark") println(arr3(2)) //spark println("-----------------------------") //变长数组(数组缓冲) //如果想使用数组缓冲,需要导入import scala.collection.mutable.ArrayBuffer包 val ab = ArrayBuffer[Int]() //向数组uanchong的尾部追加一个元素 //+=尾部追加元素 ab += 1 //追加多个元素 ab += (2,3,4,5) //追加一个数组 ++= ab ++= Array(6,7) //追加一个数组缓冲 ab ++= ArrayBuffer(8,9) //打印 println(ab) //ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9) //在数组的某个位置插入元素 insert ab.insert(0,-1,0) //在0索引的地方插入了-1 和 0 println(ab) //ArrayBuffer(-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9) //删除数组某个位置的元素 remove ab.remove(8,2) //从8索引开始删除2个元素 println(ab) //ArrayBuffer(-1, 0, 1, 2, 3, 4, 5, 6, 9) } }
4. 遍历数组
1) 增强for循环
2) until会生成角标,0 until 10 包含0包含10
2) 遍历数组代码:
object ForArrayDemo { def main(args: Array[String]) { val arr = Array(1,2,3,4,5,6,7,8) //增强for for(i <- arr) println(i) //1,2,3,4,5,6,7,8 println("----------------") //好用的until会生成一个Range //reverse是将前面生成的Range反转 for(i <- (0 until arr.length).reverse) println(arr(i)) //8,7,6,5,4,3,2,1 } }
5. 数组转换
yield关键字将原始的数组进行转换会产生一个新的数组,原始的数组不变
object ArrayYieldDemo {
def main(args: Array[String]) {
val arr = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)
//将偶数取出 *10 再生成一个新的数组
val res = for (e <- arr if e % 2 == 0) yield e * 10
println(res.toBuffer) //ArrayBuffer(20, 40, 60, 80)
println("-------------")
//更高级的写法,用着更爽
//filter是过滤,接收一个返回值为boolean的函数
//map相当于将数组中的每一个元素取出来,应用传进去的函数
val r = arr.filter(_ % 2 == 0).map(_ * 10)
println(r.toBuffer) //ArrayBuffer(20, 40, 60, 80)
}
}
6. 数组中常用的算法
object ArrayMath { def main(args: Array[String]) { val arr = Array(2,5,1,4,3) //求和 println(arr.sum) //15 //求最大、最小值 println(arr.max) //5 println(arr.min) //1 //排序 println(arr.sorted.toBuffer)//ArrayBuffer(1, 2, 3, 4, 5) } }
十二、 映射
Scala中,把哈希表这种数据结构叫做映射
1. 创建映射map
1)第一种构建Map方式 用箭头
2)第二种构建Map方式 用元祖
2. 获取和修改映射中的值
3. 全部代码:
object MappingDemo { def main(args: Array[String]) { //第一种构建Map方式 用箭头 val scores = Map("tom" -> 85,"jerry" -> 99,"kitty" -> 90) //遍历打印map scores.foreach(println) //(tom,85) (jerry,99) (kitty,90) //获取map中的值 println(scores("jerry")) //99 println("----------------------") //第二种创建Map方式,用元祖 val scores2 = Map(("tom",85),("jerry",99),("kitty",90)) //getOrElse 如果映射中有值,返回映射中的值,如果没有就返回默认值 println(scores2.getOrElse("tom",0)) //85 println(scores2.getOrElse("suke",0)) //0 } }
4. 两种map
1) 一个是immutable包下的Map,该Map中的内容不可改变。
2) 一个是mutable包下的Map,该Map中的内容可变。
十三、 元组
映射是K/V对偶的集合,对偶是元组的最简单形式。元组可以装着对个不同类型的值。
1. 创建元组
定义元组时用小括号将多个元素包起来,元素之间用逗号分隔,元素的类型可以不一样,元素的个数可以任意多个
2. 获取元组中的值
获取元组中的元素值可以使用下划线加角标,角标是从1开始。
3. 将对偶的集合转换成映射
toMap可以将对偶的集合转换成映射
4. 拉链操作
zip命令可以将多个值绑定在一起
如果两个数组的元素个数不一致,拉链操作后生成的数组的长度为较小的那个数组的元素个数
十四、 集合
Scala的集合有三大类:序列Seq、集Set、映射Map。都扩展自Iterable特质
Scala中集合有可变(mutable)和不可变(immutable)两种类型。immutable类型的集合初始化后就不能改变了(注意与val修饰的变量进行区别)
1. 序列Seq(List)
1) 不可变序列import scala.collection.immutable
在Scala中列表要么为空(Nil表示空列表)要么是一个head元素加上一个tail列表。
9 :: List(5, 2) :: 操作符是将给定的头和尾创建一个新的列表
注意::: 操作符是右结合的,如9 :: 5 :: 2 :: Nil相当于9 :: (5 :: (2 :: Nil))
2) 可变序列import scala.collection.mutable._
2. 集Set
1) 不可变的Set scala.collection.immutable.HashSet
2) 可变的Set scala.collection.mutable.HashSet
3. 映射Map
十二映射写过了。
十五、 类
1. 类的定义
2. 构造器
主构造器会执行类定义中的所有语句
十六、 对象
1. 单例对象
在Scala中没有静态方法和静态字段,但是可以使用object这个语法结构来达到同样的目的
存放工具方法和常量、高效共享单个不可变的实例、单例模式
2. 伴生对象
在Scala的类中,与类名相同的对象叫做伴生对象,类和伴生对象之间可以相互访问私有的方法和属性
3. apply方法
通常我们会在类的伴生对象中定义apply方法,当遇到类名(参数1,...参数n)时apply方法会被调用
4. 应用程序对象
Scala程序都必须从一个对象的main方法开始,可以通过扩展App特质,不写main方法
十七、 继承
1. 扩展类
在Scala中扩展类的方式和Java一样都是使用extends关键字
2. 重写方法
Scala中重写一个非抽象方法必须使用override修饰符
3. 类型检查和转换
4. 超类的构造
输出:
十八、 匹配模式和样例类
Scala有一个十分强大的模式匹配机制,可以应用到很多场合:如switch语句、类型检查等。并且Scala还提供了样例类,对模式匹配进行了优化,可以快速进行匹配
1. 匹配字符串
2. 匹配类型
注意:case y: Double if(y >= 0) => ... 模式匹配的时候还可以添加守卫条件。如不符合守卫条件,将掉入case _中
3. 匹配数组、元组
Scala中列表要么为空(Nil表示空列表)
要么是一个head元素加上一个tail列表。
:: 操作符是将给定的头和尾创建一个新的列表
4. 样例类
在Scala中样例类是一中特殊的类,可用于模式匹配。case class是多例的,后面要跟构造参数,case object是单例的
5. Option类型
在Scala中Option类型样例类用来表示可能存在或也可能不存在的值(Option的子类有Some和None)。Some包装了某个值,None表示没有值
可以使用getOrElse进行匹配
6. 偏函数
被包在花括号内没有match的一组case语句是一个偏函数。它是PartialFunction[A,B]的一个实例,A代表参数类型,B代表返回类型,常用作输入模式匹配