集合与函数的映射
- map:将集合中的每一个元素映射到某个函数
val names = List("Alice","Bob", "Nick")println(names.map(_.toUpperCase))
flatmap:将集合中的每个元素的子元素映射到某个函数并返回新的集合
val names = List("Alice","Bob", "Nick")
println(names.flatMap(_.toUpperCase()))
简化、折叠、扫描
- 折叠、化简:将二元函数引用于集合中的函数
val list = List(1,2,3,4)
val l1 = list.reduceLeft(_-_) 结果为 -8 {1-2=>?-3=>?-4}
val i2 = list.reduceRight(_-_) 结果为 -2 {3-4=>2-?=>1-?} - 折叠,简化:fold
fold函数将上一步返回的值作为函数的第一个参数继续传递参与运算,直到list中的所有元素被遍历。可以把reduceLeft看做简化版的foldLeft。相关函数:fold,foldLeft,foldRight,可以参考reduce的相关方法理解
val list2 = List(1, 9, 2, 8)
val i4 = list2.fold(5)((sum, y) => sum + y) 结果为 25 {5+1=>?+9=>?+2=>?+8}
foldRightval list3 = List(1, 9, 2, 8)
val i5 = list3.foldRight(100)(_ - _) 结果为86 {8-100=>2-?=>9-?=>1-?}
foldLeft (foldLeft和foldRight有一种缩写方法对应分别是:/:
和:\
)
val list4 = List(1, 9, 2, 8)
上例中缩写为 (list3 :\ 100)(_-_)
val i6 = (20 /: list4)(_ - _) 结果为0 {20-1=》?-9=》?-2=》?-8} 统计文字出现的次数
val sentence = "一首现代诗《笑里藏刀》:刀哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈"
val i7 = (Map[Char, Int]() /: sentence)((m, c) => m+ (c -> (m.getOrElse(c, 0) + 1)))折叠,简化,扫描
扫描,即对某个集合的所有元素做fold操作,但是会把产生的所有中间结果放置于一个集合中保存
val i8 = (1 to 10).scanLeft(0)(_ + _)
结果为 Vector(0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55)
拉链
val list1 = List("15837312345","13737312345", "13811332299")
val list2 = List(17, 87)
val list3 = list1 zip list2
结果为 List((15837312345,17), (13737312345,87))
流Stream
stream是一个集合。这个集合,可以用于存放,无穷多个元素,但是这无穷个元素并不会一次性生产出来,而是需要用到多大的区间,就会动态的生产,末尾元素遵循lazy规则。
- 使用#::得到一个stream
def numsForm(n: BigInt) : Stream[BigInt] = n #::numsForm(n + 1) - 传递一个值,并打印stream集合
val tenOrMore = numsForm(10)
println(tenOrMore) - 每次使用tail一次都会动态向stream集合按照规则生成新的元素
println(tenOrMore.tail.tail) 结果为 Stream(10, 11, 12, ?) - 使用map映射stream的元素并进行一些计算
println(numsForm(5).map(x => x * x)) 结果为 Stream(25, ?)
视图View
Stream的懒执行行为,你可以对其他集合应用view方法来得到类似的效果,该方法产出一个其方法总是被懒执行的集合。但是view不会缓存数据,每次都要重新计算。
找到10万以内,所有数字倒序排列还是它本身的数字
val viewSquares = (1 to 100000).view.map(x => {
x.toLong * x.toLong
}).filter(x => {
x.toString == x.toString.reverse
})
println(viewSquares(3))
for(x <- viewSquares){
print(x + ",")
}
线程安全集合
所有线程安全的集合都是以Synchronized开头的集合,例如
SynchronizedBuffer SynchronizedMap SynchronizedPriorityQueue SynchronizedQueue SynchronizedSet SynchronizedStack |
并行集合
Scala为了充分使用多核CPU,提供了并行集合(有别于前面的串行集合),用于多核环境的并行计算。
主要用到的算法有:
Divide and conquer : 分治算法,Scala通过splitters,combiners等抽象层来实现,主要原理是将计算工作分解很多任务,分发给一些处理器去完成,并将它们处理结果合并返回
Work stealin:算法,主要用于任务调度负载均衡(load-balancing),通俗点完成自己的所有任务之后,发现其他人还有活没干完,主动(或被安排)帮他人一起干,这样达到尽早干完的目的。
操作符
- 如果想在变量名、类名等定义中使用语法关键字(保留字),可以配合反引号反引号
val `val` = 42 - 上面这种形式叫中置操作符,A操作符B等同于A.操作符(B)
- 后置操作符,A操作符等同于A.操作符,如果操作符定义的时候不带()则调用时不能加括号
- 前置操作符,+、-、!、~等操作符A等同于A.unary_操作符
- 赋值操作符,A操作符=B等同于A=A操作符B