scala是运行在JVM上的多范式(多种编程方法)编程语言,同时支持面向对象和面向函数编程
- 开发大数据应用程序(Spark程序、Flink程序)
- 表达能力强,一行代码抵得上Java多行,开发速度快
- 兼容Java,可以访问庞大的Java类库,例如:操作mysql、redis、freemarker、activemq等等
scala程序运行需要依赖于Java类库,必须要有Java运行环境,scala才能正确执行
如何进入scala shell 直接输入scala +回车
如何退出 :quit +回车
打印:println(“hello word”)
变量的声明
scala> var aa:Int = 10
aa: Int = 10
scala> val bb:Int = 20
bb: Int = 20
- val定义的是不可重新赋值的变量
- var定义的是可重新赋值的变量
类型推断
scala> var aa=100
aa: Int = 100
scala> var aa="100"
aa: String = 100
惰性赋值
惰性计算声明惰性变量,不消耗内存空间,只有在使用时才会占用,不使用不占用空间。
scala> lazy val cc="123456789"
cc: String = <lazy>
字符串
双引号、 三引号 、插值表达式
双引号
scala> var aa="100"
aa: String = 100
三引号
scala> var aaaa="""123
| 456
| 789
| aaa
| bbb
| ccc"""
aaaa: String =
123
456
789
aaa
bbb
ccc
插值表达式
scala> var dd=s"123 ${aa}"
dd: String = 123 100
在定义字符串之前添加s
使用${}引用变量
Scala数据的类型
基础类型 | 类型说明 |
Byte | 8位带符号整数 |
Short | 16位带符号整数 |
Int | 32位带符号整数 |
Long | 64位带符号整数 |
Char | 16位无符号Unicode字符 |
String | Char类型的序列(字符串) |
Float | 32位单精度浮点数 |
Double | 64位双精度浮点数 |
Boolean | true或false |
- scala中所有的类型都使用大写字母开头
- 整形使用Int而不是Integer
运算符
类别 | 操作符 |
算术运算符 | +、-、*、/ |
关系运算符 | >、<、==、!=、>=、<= |
逻辑运算符 | &&、||、! |
scala中没有,++、--运算符
与Java不一样,在scala中,可以直接使用==、!=进行比较
Scala类型层次结构
If表达式
scala> var qq = if(100>90) 1 else 0
qq: Int = 1
不支持三元表达式
支持块表达式
scala> var qq = if(100>90) { 1 } else { 0}
qq: Int = 1
循环
scala> var num=1.to(10)
scala> for( a <- num ) println(a)
1
2
3
4
5
6
7
8
9
10
scala> for( a <- 1 to 10 ) println(a)
1
2
3
4
5
6
7
8
9
10
嵌套循环
scala> for(i <- 1 to 3; j <- 1 to 5) {print("*");if(j == 5) println("")}
*****
*****
*****
for(i <- 1 to 3 ) {
for(j <- 1 to 5){
print("*");
if(j == 5) println("")
}
}
*****
*****
*****
循环守卫
scala> for(a<-1 to 10 if a%3==0)println(a)
3
6
9
推导式
scala> for(a<-1 to 10 if a%3==0)yield a*10-5
res9: scala.collection.immutable.IndexedSeq[Int] = Vector(25, 55, 85)
scala> for(a<-1 to 10 if a%3==0)yield a*10-5*2
res10: scala.collection.immutable.IndexedSeq[Int] = Vector(20, 50, 80)
While循环
scala> var i=1
i: Int = 1
scala> while(i<=10){
| println(i)
| i=i+1
| }
1
2
3
4
5
6
7
8
9
10
Break 和continue
模拟break
import scala.util.control.Breaks._
scala> breakable{
| for(i <- 1 to 100) {
| if(i >= 50) break()
| else println(i)
| }
| }
1
2
3
4
5
模拟continue
scala> for(i <- 1 to 100 ) {
| breakable{
| if(i % 10 == 0) break()
| else println(i)
| }
| }
1
2
3
4
5
6
7
8
方法(fangfa)
scala> def add(a:Int,b:Int)=a+b
add: (a: Int, b: Int)Int
scala>
scala> add(10,11)
res14: Int = 21
返回类型推断
scala> def add(a:Int,b:Int)=a+b
add: (a: Int, b: Int)Int
scala> def add(a:Int,b:Int)=a+b+""
add: (a: Int, b: Int)String
方法的参数
默认参数、带名参数、变长参数
默认参数
scala> def add(a:Int=1,b:Int=10)=a+b
add: (a: Int, b: Int)Int
scala> add()
res17: Int = 11
带名参数
scala> add(b=3)
res20: Int = 4
变长参数
scala> def sum(a:Int*)=a.sum
sum: (a: Int*)Int
scala> sum(1,2,3,4)
res22: Int = 10
scala> sum(1,2,3,4,5,6,7,8,9,10)
res23: Int = 55
方法分调用
后缀调用、中缀调用、花括号调用、无括号调用
后缀调用
scala> Math.abs(-100)
res25: Int = 100
中缀调用
scala> Math abs -100
res26: Int = 100
花括号调用
scala> Math.abs{-100}
res28: Int = 100
无括号
如果方法没有参数,可以省略方法名后面的括号
scala> def mm()=println("wwwwwwwwwwww")
mm: ()Unit
scala> mm()
wwwwwwwwwwww
函数
scala> val add=(a:Int,b:Int)=>a+b
add: (Int, Int) => Int = <function2>
方法不能赋值给变量,函数可以赋值给变量
方法转换成函数
scala> val a=add _
a: (Int, Int) => Int = <function2>
scala>
数组
定长数组、不定长数组
定长数组
scala> var A1=new Array[Int](10)
A1: Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
scala> var A2=Array(1,2,3,4,5)
A2: Array[Int] = Array(1, 2, 3, 4, 5)
不定长数组
scala> var AB1=new ArrayBuffer[Int]()
AB1: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()
scala> var AB2=ArrayBuffer(1,2,3,4)
AB2: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4)
不定长数组的添加删除数据
- 使用+=添加元素
- 使用-=删除元素
- 使用++=追加一个数组到变长数组
scala> AB2+=5
res33: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4, 5)
scala> AB2+=6
res34: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4, 5, 6)
scala> AB2+=7
res35: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4, 5, 6, 7)
scala> AB2-=1
res37: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(2, 3, 4, 5, 6, 7)
scala> AB2-=2
res38: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(3, 4, 5, 6, 7)
scala> AB2++=Array(8,9,10)
res40: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(3, 4, 5, 6, 7, 8, 9, 10)
数组的遍历
For循环遍历、通过索引遍历、until
scala> for(a<-AB2)println(a)
3
4
5
6
7
8
9
10
scala> for(a<- 0 to AB2.length - 1 )println(AB2(a))
3
4
5
6
7
8
9
10
scala> for(a<- 0 until AB2.length)println(AB2(a)) //包含0,不包含n
3
4
5
6
7
8
9
10
数组的常用算法
scala> AB2.sum
res49: Int = 52
scala> AB2.max
res50: Int = 10
scala> AB2.min
res51: Int = 3
scala> AB2.sorted
res52: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(3, 4, 5, 6, 7, 8, 9, 10)
scala> AB2.sorted.reverse
res53: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(10, 9, 8, 7, 6, 5, 4, 3)
元组
元组可以用来包含一组不同类型的值
scala> var Y1=("zhangsan",20,1,true)
Y1: (String, Int, Int, Boolean) = (zhangsan,20,1,true)
使用_1、_2、_3....来访问元组中的元素
scala> Y1._1
res54: String = zhangsan
scala> Y1._2
res55: Int = 20
scala> var Y2=((1,2,3,4,5),("a","b","c"),("AA","BB","CC"))
Y2: ((Int, Int, Int, Int, Int), (String, String, String), (String, String, String)) = ((1,2,3,4,5),(a,b,c),(AA,BB,CC))
scala> Y2._3._3
res64: String = CC
scala> Y2._1._5
res66: Int = 5
scala> Y2._2._2
res67: String = b
列表(Liebiao)
不可变列表、可变列表
- 可以保存重复的值
- 有先后顺序
scala> var L1=List(1,2,3,4)
L1: List[Int] = List(1, 2, 3, 4)
scala>
不定长列表(可变)
scala> import scala.collection.mutable.ListBuffer
import scala.collection.mutable.ListBuffer
scala> var L2=ListBuffer(1,2,3,4,5,6)
L2: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4, 5, 6)
scala>
- 获取元素(使用括号访问(索引值)
scala> L2(2)
res1: Int = 3
- 添加元素(+=)
scala> L2+=7
res2: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4, 5, 6, 7)
- 追加一个列表(++=)
scala> L2++=List(9,10,11)
res5: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
- 更改元素(使用括号获取元素,然后进行赋值)
scala> L2(2)=3333
- 删除元素(-=)
scala> L2-=1
res13: scala.collection.mutable.ListBuffer[Int] = ListBuffer(2, 3333, 4, 5, 6, 7, 8, 9, 10, 11)
- 转换为List(toList)
scala> L2.toList
res16: List[Int] = List(3333, 4, 5, 6, 7, 8, 9, 10, 11)
- 转换为Array(toArray)
scala> L2.toArray
res18: Array[Int] = Array(3333, 4, 5, 6, 7, 8, 9, 10, 11)
列表的常用操作
scala> var L3=ListBuffer(1,2,3,4,5,6,7)
L3: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4, 5, 6, 7)
scala> var L4=ListBuffer(5,6,7,8,9,10)
L4: scala.collection.mutable.ListBuffer[Int] = ListBuffer(5, 6, 7, 8, 9, 10)
scala>
是否为空
scala> L3.isEmpty
res19: Boolean = false
列表拼接
scala> L3++L4
res20: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4, 5, 6, 7, 5, 6, 7, 8, 9, 10)
获取列表的第一个数据
scala> L3.head
res21: Int = 1
获取列表的第一个数据之外的数据
scala> L3.tail
res22: scala.collection.mutable.ListBuffer[Int] = ListBuffer(2, 3, 4, 5, 6, 7)
获取列表前N个数据
scala> L3.take(3)
res23: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3)
获取列表后N个数据(drop(List的大小-N)) 删除掉数据(N)后剩余的数据
scala> L3.drop(4)
res24: scala.collection.mutable.ListBuffer[Int] = ListBuffer(5, 6, 7)
转换成String
scala> L3.toString
res28: String = ListBuffer(1, 2, 3, 4, 5, 6, 7)
生成一个字符串
scala> L3.mkString
res29: String = 1234567
scala>
交集
scala> L3.intersect(L4)
res32: scala.collection.mutable.ListBuffer[Int] = ListBuffer(5, 6, 7)
差集
scala> L3.diff(L4)
res34: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4)
并集
scala> L3.union(L4)
res35: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4, 5, 6, 7, 5, 6, 7, 8, 9, 10)
扁平化
scala> var L5=List(List(1,2),List(3,4),List(5,6))
L5: List[List[Int]] = List(List(1, 2), List(3, 4), List(5, 6))
scala> L5.flatten res36: List[Int] = List(1, 2, 3, 4, 5, 6)
|
拉链/拉开
scala> var L11 =List("zhangsan","lisi","wangwu","zhaoliu")
L11: List[String] = List(zhangsan, lisi, wangwu, zhaoliu)
scala> var L22 =List(11,22,33,44)
L22: List[Int] = List(11, 22, 33, 44)
scala> L11.zip(L22)
res39: List[(String, Int)] = List((zhangsan,11), (lisi,22), (wangwu,33), (zhaoliu,44))
scala> res39.unzip
res41: (List[String], List[Int]) = (List(zhangsan, lisi, wangwu, zhaoliu),List(11, 22, 33, 44))
Set
可变集、不可变集
Set(集)是代表没有重复元素的集合
- 元素不重复
- 不保证插入顺序
不可变集
scala> var S2=Set(1,1,1,1,1,1,2,3,4,5,6)
S2: scala.collection.immutable.Set[Int] = Set(5, 1, 6, 2, 3, 4)
scala> S2.size
res1: Int = 6
常用的操作
scala> S2-1
res2: scala.collection.immutable.Set[Int] = Set(5, 6, 2, 3, 4)
scala> S2+77
res4: scala.collection.immutable.Set[Int] = Set(5, 1, 6, 77, 2, 3, 4)
scala> S2++Set(8,9)
res7: scala.collection.immutable.Set[Int] = Set(5, 1, 6, 9, 2, 3, 8, 4)
scala> S2++List(88,99)
res8: scala.collection.immutable.Set[Int] = Set(88, 5, 1, 6, 2, 3, 99, 4)
可变集
import scala.collection.mutable.Set
scala> var S3=Set(1,2,3,4,5)
S3: scala.collection.mutable.Set[Int] = Set(1, 5, 2, 3, 4)
scala> S3+=6
res9: scala.collection.mutable.Set[Int] = Set(1, 5, 2, 6, 3, 4)
scala> S3-=1
res12: scala.collection.mutable.Set[Int] = Set(5, 2, 6, 3, 7, 4)
映射
可变映射、不可变映射
不可变映射
scala> var M1=Map("zhangsan"->20,"lisi"->30)
M1: scala.collection.immutable.Map[String,Int] = Map(zhangsan -> 20, lisi -> 30)
scala> var M2=Map(("zhangsan",0),("lisi",30))
M2: scala.collection.immutable.Map[String,Int] = Map(zhangsan -> 0, lisi -> 30)
常用操作
遍历
scala> for( (a,b) <- M1 )println( s"${a} ${b} " )
zhangsan 20
lisi 30
scala> M1("zhangsan")
res16: Int = 20
scala> M1.keys
res18: Iterable[String] = Set(zhangsan, lisi)
scala> M1.values
res19: Iterable[Int] = MapLike(20, 30)
scala> M1.getOrElse("wangwu","-------------------")
res28: Any = -------------------
可变Map
import scala.collection.mutable.Maps
scala> var M2=Map("zhangsan"->200,"lisi"->300)
M2: scala.collection.mutable.Map[String,Int] = Map(lisi -> 300, zhangsan -> 200)
scala> M2+="wangwu"->500
res29: scala.collection.mutable.Map[String,Int] = Map(lisi -> 300, zhangsan -> 200, wangwu -> 500)
scala> M2-="zhangsan"
res31: scala.collection.mutable.Map[String,Int] = Map(lisi -> 300, wangwu -> 500)
迭代器
scala> var a=List(1,2,3,4,5)
a: List[Int] = List(1, 2, 3, 4, 5)
scala> var ite=a.iterator
ite: Iterator[Int] = non-empty iterator
scala> while(ite.hasNext){
| println(ite.next)
| }
1
2
3
4
类和对象
类使用class 声明
下划线指定默认值: 要求:变量必须指定一个类型
Scala中没有public,没有背修饰的全部标识公共的,使用private修饰的标识私有的
代码参见demo02
类的构造器
主构造器、辅助构造器
主构造器
声明class时直接指定属性。在new 时也直接实行属性值。
辅助构造器:除了主构造器之外的构造器。
固定格式
def this(arr:Array[String]){ this(arr(0),arr(1)) } |
单例对象
单例对象表示全局仅有一个对象
- 把class换成object
可以使用object直接引用成员变量
Main
Main方法只能放在单例对象中
单例对象继承App,运行
伴生对象
一个class和object具有同样的名字。这个object称为伴生对象,这个class称为伴生类
- 伴生对象和伴生类可以互相访问private属性
Scala的用法-10
继承
- 可以在子类中定义父类中没有的字段和方法,或者重写父类的方法
样例类
可以用来快速定义一个用于保存数据的类
case class caseclass1(name:String,var age:Int)
- apply方法可以快速创建一个对象(可以不使用new关键字)
- toString方法返回 类名(数据1,数据2)
- equals方法 判断两个对象数据是否相同
- hashCode方法计算一个对象的hashCode码
- copy方法 复制一个对象
样例对象
- 定义枚举
trait Sex
case object nan extends Sex
case object nv extends Sex
模式匹配
变量 match {
case "常量1" => 表达式1
case "常量2" => 表达式2
case "常量3" => 表达式3
case _ => 表达式4 // 默认匹配
}
模式匹配可以有的返回值,可以添加守卫(if判断)
可以做如下匹配
匹配字符串【*】
匹配数据的配型【*】
匹配样例类【*】
匹配集合
匹配列表
匹配元组
声明变量中模式匹配
Option类型
- 用来有效避免空引用(null)异常
- Some(x):表示实际的值
- None:表示没有值
· object Option {
def dvi(a:Int,b:Int) ={ def main(args: Array[String]): Unit = { · |
var aa=dvi(6,0).getOrElse("无结果") println(aa)
|
文章评论