#scala字符串插值(拼接)
# s 利用之后学习的隐式转换实现
var name = “henry”
println(s"my name is $name")
println(s"1 and 1 eq KaTeX parse error: Expected 'EOF', got '#' at position 48: …>1 and 1 eq 2 #̲ f 简单格式化 var …name%s,age=
a
g
e
age%d,score=
agescore%2.2f,gender=$gender%c")
=>name=henry,age=18,score=88.90,gender=男
# raw 所见所得,不转译
println(s"a\tb\nc\td")
println("-----------")
println(raw"a\tb\nc\td")
=>a b
=>c d
=>-----------
=>a\tb\nc\td
#程序控制
#if表达式类型推断
var b:Int = 5;
var a = if(b>5) “a” else 2.0
String => AnyRef => Any
Double => AnyVal => Any
#因此 a =>Any
var b:Int =5;
var a = if(b>5) "a"
println(a)
=>()
#如果没有else则值为Unit即()
#REPL环境:lunix/dos
#默认只能解释一行
:paste
// Entering paste mode (ctrl-D to finish)
#多行命令解析
#ctrl+D 退出编辑并执行
//Exiting paste mode, now interpreting.
#块表达式{}
#也是一个结果,{}中最后一行的结构就是块表达式的结果
var a ={
var a = 6;var b=5;
a*b
}
println(a)
=>()
#循环控制
#i无须声明,也不可以声明,可以是作用域内现有变量
#<-为关键字非操作符,类似java中的:
#表达式为数组、元组、集合
#在scala中Range是常用的集合类型,表示范围区间
#单循环
for(i<-表达式){
statements
}
#Range min to/until max by step
#从数值min开始以step作为步长行走直至max结束
#to 包含 max
#until 不包含 max
for(i<- 1 to 10 by 2;if(i%3==0)){
println(i)
}
#简化
for(i<- 1 to 10 by 2 if i%3==0 if i>5){
println(i)
}
#多重循环
for(i<- 表达式1;j<-表达式2;...){
statements
}
for(i<- 1 to 20 if i%2==0;j<-1 to i if j%3 ==0){
println(s"$i\t$j")
}
#注意:如果()中有多个表达式,可以使用{}代替,换行写多条语句
for{i<-1 to 20 if i%2==0
j<-1 to i if j%3==0}{
println(s"$i\t$j")
}
#循环跳转语句:scala中没有break
#导入包
import scala.until.control.Breaks._
#源码
def breakable(op: => Unit) {
try {
op
} catch {
case ex: BreakControl =>
if (ex ne breakException) throw ex
}
}
def break():Nothing = { throw breakException }
#通过异常机制实现中断
#._相当于java中的.*
import scala.util.control.Breaks._
breakable {
for {i <- 1 to 20 if i % 2 ==0
j <- 1 to i if j %3 ==0}{
if((i+j)%5 ==0) {
break
}
println(s"$i\t$j")
}
}
#推导式:yield循环的结果输出生成集合Vector
var arr = for (i<-1 to 20 if i%2==0) yield i
#数据结构
#创建
#类:动态内容
Class A ...
var a:A = new A();
#伴生对象:静态内容
object A ...
#数组、栈、队列、链表、树、散列表
#线性结构 Array 、Seq 、List 、Map 、Set
#scala中结合有mutable和immutable两种类型,而java中的结构容量都是可变的
#内容可变
#数组(容量不可变)
#标准方式:初始化:String默认值null,Int默认值0.未指定Nothing默认值null
var arr:Array[T] = new Array[T](capacity:Int)
var len:Int = arr.length #固定容量:capacity
arr(index:Int) = value
arr+=value #头部追加
println(arr(index:Int))
arr.foreach(println) #数组遍历
arr.foreach(x=>{println(s"$x,")})
#二维
var arr = Array.ofDim[Type](row:Int,col:Int)
arr(rowIndex)(colIndex) = VALUE
arr.foreach(x=>x.foreach(println))
#值已知
var arr:Array[T] = Array(T v1,...)
var arr:Array[Int] = Array.range(begin,end,step)
#数组(容量可变)
import scala.collection.mutable.ArrayBuffer
var arr:ArrayBuffer[T] = new ArrayBuffer[T] (capacity:Int)
var len:Int = arr.length #实际元素数量
arr.append(item:Int) <=> arr+=item:Int #改变长度只能用append或+=
arr(index:Int (0~arr.length-1)) #修改已有元素可以使用()
#元祖
#固定22个Tuple:Tuple1~Tuple22,单个Tuple最多存22个元素
#除了Tuple外,其他可以用()直接创建
var tp1=(1);
println(tp1.getClass)=>Int
var tp1 = (1,2)
println(tp1.getClass) => scala.Tuple2$mcII$sp
var tp1 = (1,2,3,...) => scala.TupleN 元素的数量n决定类型
var tp2 = new Tuple1(1) #可以存1~22个值
println(tp2.getClass) => scala.Tuple1$mcI$sp
var tp2 = new Tuple1(1,2)
println(tp2.getClass) =>scala.Tuple1
var tp2 = new Tuple2(1,2) #只能存两个元素(键值对)
println(tp2.getClass) => scala.Tuple2$mcII$sp
var tp2 = new TupleN(v1,...) #只能存n个元素
var tp3 = "henry"->88
val(key,value) = tp3 #同时将tp3中的值依次赋值给两个变量key,value
println(tp3.getClass()) => scala.Tuple2
println(s"$key\t$value") =>henry 88
#元祖不支持遍历
for(i<-tp1){println(i)} #报错
#元祖提供了迭代功能
println(s"${tp1._1}\t${tp1._2}\t${tp1._3}")
tp3.productIterator.foreach(println)
for(i<- tp1.productIterator){
println(i)
}
#元祖不可变,一旦创建无法改变内容和长度
#列表的常用操作
#immutable
var list = List[Int](1,3,11,9,6)
#:面向集合,值在后尾部追加,否则头部追加
#【不可变】:+ 或 +: 返回新集合,而list不变
var c = list :+ 13
var d = 15 +: c
#遍历
lst.foreach(x=>{print(x+",")}) =>1,3,11,9,6
println()
c.foreach(x=>{print(x+",")}) =>1,3,11,9,6,13
println()
d.foreach(x=>{print(x+",")}) =>15,1,3,11,9,6,13
#mutable
import scala.collection.mutable.ListBuffer
var lb = new ListBuffer[Int]
lb += 12 => 12 #向集合中追加元素
lb += (14,15) => 12 14 15
List(9,7) ++=: lb =>9,7,12,14,15 #向集合中追加元素
var lc = lb :+ 13 => lc:12 14 15 13 #lb不变
#分组
import scala.util.Random
#分组
import scala.util.Random
var arr = List(Random.nextInt(20),Random.nextInt(20),Random.nextInt(20),Random.nextInt(20),
Random.nextInt(20),Random.nextInt(20),Random.nextInt(20));
arr.foreach(println) => 14,12,12,11,8,1,0
arr.grouped(3).foreach(println)
List(14,12,12)
List(11,8,1)
List(0)
#比较地址:如果需要比较两个数组的值该怎么办? ------
# a1 == a2
== <=> eq
!=
# ++ 合并---------------------------
scala> a++b
res0: Array[Any] = Array(1,2,3,henry,pola,ariel)
#:+ 尾部追加------------------------
#对比ArrayBuffer append/prepend
scala> a:+5
res3:Array[Int] = Array(1,2,3,5)
#+: 头部追加-------------------
scala> 9+:a
res4:Array[Int] = Array(9,1,2,3)
# /: 从左向右累加(过期用foldLeft代替)---------
# arrItem 左~右依次取值
# arr.foldLeft(initValue)((aggRst,arrItem)=>{...}) <=> fold/foldLeft
scala> a.foldLeft(10)((x,y)=>{println(s"$x\t$y");x+y})
10 1 0+10
11 2 0+1+10
13 3 0+1+2+10
res10: Int = 16
#:\ 从右向左累加(过期用foldRight代替) ---------
scala> a.foldRight(10)((x,y)=>{println(s"$x\t$y");x+y})
3 10 0+10
2 13 0+3+10
1 15 0+3+2+10
res15:Int = 16
#addString 将数组拼接为字符串---------------
#arr.addString(b:StringBuilder[,start:String,sep:String,end:String])
import scala.collection.mutable.StringBuilder
var builder = new mutable.StringBuilder
a3.addString(builder,"[",",","]")
println(builder)
#aggregate 聚合函数--------------
#arr.aggregate(initValue)(mapCal,reduceCal)
#map端聚合mapCal生效,不走reduce端reduceCal失效
#arr.par..aggregate(initValue)(mapCal,reduceCal)
#par产生分区,mapCal->reduceCal
var a = Array(1,2,3,10,13,21);
println(a.aggregate(0)((x:Int,y:Int) => {
println(s"$x + $y = ${x+y}")
x + y
},(x:Int,y:Int) => {
println(s"$x - $y = ${x-y}")
x - y
}))
=>
0 + 1 =1
1 + 2 =3
3 + 3 =6
6 + 10 =16
16 + 13 =29
29 + 21 =50
50
println(a.par.aggregate(0)((x:Int,y:Int) =>{
println(s"$x + $y = ${x+y}")
x + y
},(x:Int,y:Int) =>{
println(s"$x - $y = ${x-y}")
x-y
}))
0 + 1 =1
0 + 3 =3
0 + 13=13
0 + 2=2
0 + 21=21
0 + 10=10
13 - 21 = -8
2 - 3 = -1
10 - - 8 = 18
1 - - 1 = 2
2 - 18 = -16
-16
#andThen ------------------
#f1 和f2只有【一个参数】且类型相同 f1 的输出为f2 的输入
# def f = f1 andThen f2 先调用f1,再调用f2
val add = (x:Int) =>{
println("add")
x+10
}
val mul = (x:Int) => {
println("mul")
x*11
}
def mat = add andThen mul
println(mat(2))
=>add
mul
132
a.andThen(x=>{}) =>PartialFunction[Int,C]
a.andThen(x=>{if(x%2==0) x})(0) => 如果下标0位偶数输出该数,否则输出Unit:()
#compose
#def f =f1 andThen f2 先调用f2,再调用f1
def mcm = add compose mul
println(mcm(2))
=>mul
add
32
#apply 根据索引取元素------------------
#T t = arr.apply(index)
a.apply(2) =>3
#applyOrElse-----------------------
#T t = a.applyOrElse(index,{item:Int=>DEFAULT VALUE})
#根据下标取数组元素,如果越界,则返回默认值
#第二个参数为偏函数
println(a.applyOrElse(20,{i:Int =>"NONE" }}} =>NONE
println(a.applyOrElse(0,{i:Int => "NONE" }}} => 1
#canEqual 两个结合之间是否可以比较-------------
#集合中都可以比单equals比较地址
#charAt(index) 根据缩影取字符,只能用户字符数组----
#clone【浅克隆】一个数组的副本——-------
#若数组的类型为AnyRef,则副本中存储的是对象引用
#collect collectFirst
#a1.collect[First] (PartialFunction)
var arr = Array(11,25,9,22,3,16,18,21,36)
arr.collect({case i if(i%2 ==0)=>i}).foreach(println)
=>22,16,18,36 #Array
arr.collectFirst({case i if(i%2==0)=>i}).foreach(println)
=>22 #Some(22)
#combinations(n) 排序结合,不考虑顺序——----------
#n任意选择集合中n个元素进行组合
var a3 = Array('a','b','c');
a3.combinations(2).foreach(x=>{x.foreach(print);println()})
=>ab
=>ac
=>bc
#permutations 所有元素不同顺序的排列
scala>a3.permutations.foreach(x=>println(x.mkString(",")))
a,b,c
a,c,b
b,a,c
b,c,a
c,a,b
c,b,a
#contains(n)集合中是否包含元素n---------------
#containsSlice(GenSeq)序列中是否包含子序列
#子序列必须【有序】的【连续】的出现才返回true
#copyToArray(Array[,destStartPos[,destLen]])----------------
#将集合中的元素从0开始,拷贝到参数1数组从startPos开始长度为len的数组中
#copyToBuffer(Buffer)将集合中的所有元素拷贝至参数Buffer中
#a1.corresponds(a2)((x,y)=>Boolean)--------------------sameElements
#a1和a2的长度相等,且a1和a2同一个位置的元素必须符合条件
#count((x)=>Boolean)统计符合条件的元素数量------------
arr.count(_%2==0)
arr.count(x=>x>=5 && x<=20)
#a1.diff(a2)返回a1相对于a2的差集-------------
#a1不在a2中的元素
#a1.intersect(a2) 返回a1相对于a2的交集-------------
#distinct集合去重----------------
#array.distinct <=> array.toSet
#删除操作:不改变源数组,生成新数组
#drop(n)删除数组左侧的n个元素-----------
#dropRight(n) 删除数组右侧的n个元素-----------
#dropWhile(p:Type =>Boolean)删除数组中符合条件的元素--
#若第一个元素就不符合条件,则不删除
#从第一个符合条件的开始删除,到第一个不符合条件的结束