Scala编程语言
1.什么是Scala
Scala是一种多范式的编程语言,它将面向对象和函数式编程结合在一个简洁的高级语言中,Scala运行于Java平台(Java虚拟机),并兼容现有的Java程序。
2.为什么要学Scala
优雅:这是框架设计师第一个要考虑的问题,框架的用户是应用开发程序员,API是否优雅直接影响用户体验。
速度快:Scala语言表达能力强,一行代码抵得上Java多行,开发速度快;Scala是静态编译的,所以和JRuby,Groovy比起来速度会快很多。
能融合到Hadoop生态圈:Hadoop现在是大数据事实标准,Spark并不是要取代Hadoop,而是要完善Hadoop生态。JVM语言大部分可能会想到Java,但Java做出来的API太丑,或者想实现一个优雅的API太费劲。
3.Scala基础语法
1.声明变量
package com.lyz.scala.day1
Object HelloScala{
def main(args: Array[String]):Unit={
//使用val定义的变量值是不可变的,相当于java里用final修饰的变量
val i = 1
//使用var定义的变量是可变得,在Scala中鼓励使用val
var s = "hello"
//Scala编译器会自动推断变量的类型,必要的时候可以指定类型
//变量名在前,类型在后
val str: String = "itcast"
}
}
2.常用类型
Scala和Java一样,有7种数值类型Byte、Short、Int、Long、Char、Float和Double(无包装类型)和一个Boolean类型
3.条件表达式
object ConditionDemo {
def main(args: Array[String]): Unit = {
val x = 1
//判断x的值,将结果赋给y
val y = if (x > 0) 1 else -1
//打印y的值
println("y="+y)
//支持混合类型表达式
val z =if (x>0) x else if (x<0) -1 else "error"
println("z="+z)
//如果缺失else,相当于if (x > 2) 1 else ()
val m = if (x > 2) 1
println("m="+m)
//在scala中每个表达式都有值,scala中有个Unit类,写做(),相当于Java中的void
val n = if (x > 2) 1 else ()
println("n="+n)
}
}
4.块表达式
package com.lyz.scala.day1
/*
块表达式
*/
object BlockExpressionDemo {
def main(args: Array[String]): Unit = {
val x =4
//在scala中{}中课包含一系列表达式,块中最后一个表达式的值就是块的值
//下面就是一个块表达式
val y = {
if (x<0) -1
else if(x>0) 1
else "error"
}
println(y)
}
}
5.循环
在scala中有for循环和while循环,用for循环比较多
package com.lyz.scala.day1
/*
for循环
*/
object ForDemo {
def main(args: Array[String]): Unit = {
//for(i <- 表达式),表达式1 to 10返回一个Range(区间)
//每次循环将区间中的一个值赋给i
for(i<- 1 to 10)
print(i+" ")
println()
//for(i <- 数组)
val arr = Array("a","b","c")
for(i <- arr)
print(i+" ")
println()
//高级for循环
//每个生成器都可以带一个条件,注意:if前面没有分号
for(i <- 1 to 3;j<- 1 to 3; if i!=j)
print((10*i+j)+" ")
println()
//for推导式:如果for循环的循环体以yield开始,则该循环会构建出一个集合
//每次迭代生成集合中的一个值
val z = for(i<- 1 to 10) yield i *10
print(z)
// 答案如下:
/*
1 2 3 4 5 6 7 8 9 10
a b c
12 13 21 23 31 32
Vector(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
*/
}
}
6 定义方法
方法的返回值类型可以不写,编译器可以自动推断出来,但是对于递归函数,必须指定返回类型
7.定义函数
8.方法与函数的区别
在函数式编程语言中,函数是“头等公民”,它可以像任何其他数据类型一样被传递和操作
案例:首先定义一个方法,再定义一个函数,然后将函数传递到方法里面
/*
定义方法
*/
object function {
val func =(x:Int)=> x * 10
//定义一个方法,里面传入一个函数
def f1(f:Int=> Int): Int ={
f(3)
}
def main(args: Array[String]): Unit = {
val f2 =f1(func)
println(f2)
}
object function1 {
//定义一个方法,调用函数
def m1(f:(Int,Int)=>Int):Int ={
f(2,6)
}
//定义一个函数
val f1 =(x:Int,y:Int)=>x*y
val f2 =(x:Int,y:Int)=>x+y
def main(args: Array[String]): Unit = {
val s =m1(f1)
println(s)
val s1 =m1(f2)
println(s1)
}
}
9.将方法转换成函数(神奇的下划线)
10. 数组
1) 定长数组
import scala.collection.mutable.ArrayBuffer
object sortDemo1 {
def main(args: Array[String]): Unit = {
//初始化一个长度为8的定长数组,其所有元素均为0
val arr1 = new Array[Int](8)
//直接打印定长数组,内容为数组的hashcode值
println(arr1) //[I@6debcae2
//将数组转换成数组缓冲,就可以看到原数组中的内容了
//toBuffer会将数组转换长数组缓冲
println(arr1.toBuffer) //ArrayBuffer(0, 0, 0, 0, 0, 0, 0, 0)
//注意:如果new,相当于调用了数组的apply方法,直接为数组赋值
//初始化一个长度为1的定长数组
val arr2 = Array[Int](10)
println(arr2.toBuffer) //ArrayBuffer(10)
//定义一个长度为3的定长数组
val arr3 = Array("hadoop", "storm", "spark")
//使用()来访问元素
println(arr3(2)) //spark
}
}
2).变长数组
object sortDemo1 {
def main(args: Array[String]): Unit = {
//变长数组(数组缓冲)
//如果想使用数组缓冲,需要导入import scala.collection.mutable.ArrayBuffer包
val ab = ArrayBuffer[Int]()
//向数组缓冲的尾部追加一个元素
//+=尾部追加元素
ab += 1
println(ab) //ArrayBuffer(1)
//追加多个元素
ab += (2, 3, 4, 5)
println(ab) // ArrayBuffer(1, 2, 3, 4, 5)
//追加一个数组++=
ab ++= Array(6, 7)
println(ab) //ArrayBuffer(1, 2, 3, 4, 5, 6, 7)
//追加一个数组缓冲
ab ++= ArrayBuffer(8,9)
println(ab) //ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9)
//打印数组缓冲ab
//在数组某个位置插入元素用insert
ab.insert(0, -1, 0)
println(ab) //ArrayBuffer(-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
//删除数组某个位置的元素用remove
ab.remove(8, 2)
println(ab) //ArrayBuffer(-1, 0, 1, 2, 3, 4, 5, 6, 9)
}
}
3).遍历数组
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
//好用的until会生成一个Range
//reverse是将前面生成的Range反转
for(i <- (0 until arr.length).reverse)
println(arr(i)) //5 4 3 2 1 0
}
}
4).数组转换
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)
//更高级的写法,用着更爽
//filter是过滤,接收一个返回值为boolean的函数
//map相当于将数组中的每一个元素取出来,应用传进去的函数
val r = arr.filter(_ % 2 !=0).map(_ * 10)
println(r.toBuffer) //ArrayBuffer(20, 40, 60, 80)
}
}
5).数组常用算法
6).数组排序
val arr = Array(2,5,6,8,4,1,3,9)
println(arr.toBuffer.sorted) //ArrayBuffer(1, 2, 3, 4, 5, 6, 8, 9)
println(arr.toBuffer) //ArrayBuffer(2, 5, 6, 8, 4, 1, 3, 9)
println(arr.toBuffer.sortWith(_>_)) //ArrayBuffer(9, 8, 6, 5, 4, 3, 2, 1)
println(arr.toBuffer.sortWith(_<_)) //ArrayBuffer(1, 2, 3, 4, 5, 6, 8, 9)
11.映射
在Scala中,把哈希表这种数据结构叫做映射
1). 构建映射 获取元素值
/*
映射
*/
object MapDemo {
def main(args: Array[String]): Unit = {
//第一种 创建map的方式,使用箭头
val arr1 = Map("tom"-> 85,"jerry"->90,"kitty"-> 95)
println(arr1) //Map(tom -> 85, jerry -> 90, kitty -> 95)
//第二种,使用元祖创建
val arr2 =Map(("tom",85),("jerry",90),("kitty",95))
println(arr2) //Map(tom -> 85, jerry -> 90, kitty -> 95)
println(arr2("tom")) //85
}
}
getOrElse方法
12.元组
映射是K/V对偶的集合,对偶是元组的最简单形式,元组可以装着多个不同类型的值。
/*
元组
*/
object YuanZu {
def main(args: Array[String]): Unit = {
//创建元组
val t = (1,"spark",2.0)
println(t) //(1,spark,2.0)
// 获取元素,是从1开始,不是0开始
val t1 = t._1
println(t1) //1
val t2 = t._2
println(t2) // spark
val t3 = t._3
println(t3) // 2.0
}
}
将对偶的集合转换成映射
val arr = Array(("lyz",24),("rhm",20))
println(arr.toBuffer) // 输出结果为: ArrayBuffer((lyz,24), (rhm,20))
// 将对偶的集合转换成映射
println(arr.toMap) // Map(lyz -> 24, rhm -> 20)
13.集合
Scala的集合有三大类:序列Seq、集Set、映射Map,所有的集合都扩展自Iterable特质
在Scala中集合有可变(mutable)和不可变(immutable)两种类型,immutable类型的集合初始化后就不能改变了(注意与val修饰的变量进行区别)
1).序列
不可变的序列 import scala.collection.immutable._
在Scala中列表要么为空(Nil表示空列表)要么是一个head元素加上一个tail列表。
9 :: List(5, 2) :: 操作符是将给定的头和尾创建一个新的列表
注意::: 操作符是右结合的,如9 :: 5 :: 2 :: Nil相当于 9 :: (5 :: (2 :: Nil))
object ImmutListDemo {
def main (args:Array[String]): Unit={
//创建一个不可变的集合
val list = List(1,2,3)
println(list) //List(1, 2, 3)
//将0插入到lst1的前面生成一个新的List
val list2 = 0 :: list
println(list2) // List(0, 1, 2, 3)
val list3 =list.:: (0)
println(list3) // List(0, 1, 2, 3)
val list4 = 0 +:list
println(list4) // List(0, 1, 2, 3)
val list5 = list.+:(0)
println(list5) // List(0, 1, 2, 3)
//将一个元素添加到lst1的后面产生一个新的集合
val list6 = list :+ 4
println(list6) // List(1, 2, 3, 4)
//重新创建一个集合
val list0 =List(1,4,5,6)
val list7 = list0 ++ list
println(list7) //List(1, 4, 5, 6, 1, 2, 3)
//将lst1插入到lst0前面生成一个新的集合
val list8 = list ++: list0
println(list8) //List(1, 2, 3, 1, 4, 5, 6)
}
}
可变的序列 import scala.collection.mutable._
object MutListDemo extends App {
//构建一个可变列表,初始有3个元素1,2,3
val list0 = ListBuffer[Int](1,2,3)
println(list0) //ListBuffer(1, 2, 3)
//创建一个空的可变列表
val list1 = new ListBuffer[Int]
println(list1) //ListBuffer()
//向lst1中追加元素,注意:没有生成新的集合
list1+=4
println(list1) //ListBuffer(4)
list1.append(5)
println(list1) //ListBuffer(4, 5)
//将lst1中的元素最近到lst0中, 注意:没有生成新的集合
list0 ++= list1
println( list0 ) //ListBuffer(1, 2, 3, 4, 5)
//将lst0和lst1合并成一个新的ListBuffer 注意:生成了一个集合
val list2 = list0 ++ list1
println(list2) //ListBuffer(1, 2, 3, 4, 5, 4, 5)
//将元素追加到lst0的后面生成一个新的集合
val list3 = list0 :+ 5
println(list3) //ListBuffer(1, 2, 3, 4, 5, 4, 5)
}
2).Set
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_38201936/article/details/89608537