分享

scala的数据结构续集

集合元素与函数的映射
1)map:将集合中的每一个元素映射到某一个函数
  
val names = List("Alice",  "Bob", "Nick")
  
println(names.map(_.toUpperCase))
  
2) flatmapflat即压扁,压平,扁平化,效果就是将集合中的每个元素的子元素映射到某个函数并返回新的集合
  
val names = List("Alice",  "Bob", "Nick")
  
println(names.flatMap(_.toUpperCase()))
  
5.9  化简、折叠、扫描
1) 折叠,化简:将二元函数引用于集合中的函数
  
val list = List(1, 2, 3, 4, 5)
  
val i1 = list.reduceLeft(_ - _)
  
val i2 = list.reduceRight(_ - _)
  
println(i1)
  
println(i2)
  
.reduceLefft(_ - _)这个函数的执行逻辑如图所示:
file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image001.png
.reduceRight(_ -_)反之同理
2)  折叠,化简:fold
fold函数将上一步返回的值作为函数的第一个参数继续传递参与运算,直到list中的所有元素被遍历。可以把reduceLeft看做简化版的foldLeft。相关函数:foldfoldLeftfoldRight,可以参考reduce的相关方法理解。
  
val list2 = List(1, 9, 2, 8)
  
val i4 = list2.fold(5)((sum, y) => sum  + y)
  
println(i4)
  
foldRight
  
val list3 = List(1, 9, 2, 8)
  
val i5 = list3.foldRight(100)(_ - _)
  
println(i5)
  
尖叫提示:foldLeftfoldRight有一种缩写方法对应分别是:/:和:\
例如:
foldLeft
  
val list4 = List(1, 9, 2, 8)
  
val i6 = (0 /: list4)(_ - _)
  
println(i6)
  
3)  统计一句话中,各个文字出现的次数
  
val  sentence = "一首现代诗《笑里藏刀》:哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈刀哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈"
  
//m  +  (“一” -> 1, “” -> 1, “哈” -> 1)
  
val i7  = (Map[Char, Int]() /: sentence)((m, c) => m + (c -> (m.getOrElse(c, 0)  + 1)))
  
println(i7)
  
4)  折叠,化简,扫描
这个理解需要结合上面的知识点,扫描,即对某个集合的所有元素做fold操作,但是会把产生的所有中间结果放置于一个集合中保存。
  
val i8 = (1 to 10).scanLeft(0)(_ + _)
  
println(i8)
  
5.10  拉链
  
val list1 = List("15837312345",  "13737312345", "13811332299")
  
val list2 = List(17, 87)
  
println(i1)
  
5.11  迭代器
你可以通过iterator方法从集合获得一个迭代器,通过while循环和for表达式对集合进行遍历。
  
val iterator = List(1, 2, 3, 4,  5).iterator
  
while (iterator.hasNext) {
  
   println(iterator.next())
  
}
  
或:
  
for(enum <- iterator) {
  
   println(enum)
  
}
  
5.12   Stream
stream是一个集合。这个集合,可以用于存放,无穷多个元素,但是这无穷个元素并不会一次性生产出来,而是需要用到多大的区间,就会动态的生产,末尾元素遵循lazy规则。
1)  使用#::得到一个stream
  
def numsForm(n: BigInt) : Stream[BigInt]  = n #:: numsForm(n + 1)
  
2)  传递一个值,并打印stream集合
  
val tenOrMore = numsForm(10)
  
println(tenOrMore)
  
3)  tail的每一次使用,都会动态的向stream集合按照规则生成新的元素
  
println(tenOrMore.tail)
  
println(tenOrMore)
  
4)  使用map映射stream的元素并进行一些计算
  
println(numsForm(5).map(x => x * x))
  
5.13  视图 View
Stream的懒执行行为,你可以对其他集合应用view方法来得到类似的效果,该方法产出一个其方法总是被懒执行的集合。但是view不会缓存数据,每次都要重新计算。
例如:我们找到10万以内,所有数字倒序排列还是它本身的数字。
  
val  viewSquares = (1 to 100000)
  
  .view
  
  .map(x => {
  
//        println(x)
  
    x.toLong * x.toLong
  
}).filter(x  => {
  
  x.toString == x.toString.reverse
  
})
  
  
println(viewSquares(3))
  
  
for(x  <- viewSquares){
  
  print(x + "")
  
}
  
5.14  线程安全的集合
所有线程安全的集合都是以Synchronized开头的集合,例如:
  
SynchronizedBuffer
  
SynchronizedMap
  
SynchronizedPriorityQueue
  
SynchronizedQueue
  
SynchronizedSet
  
SynchronizedStack
  
5.15  并行集合
Scala为了充分使用多核CPU,提供了并行集合(有别于前面的串行集合),用于多核环境的并行计算。
主要用到的算法有:
Divide and conquer : 分治算法,Scala通过splitterscombiners等抽象层来实现,主要原理是将计算工作分解很多任务,分发给一些处理器去完成,并将它们处理结果合并返回
Work stealin:算法,主要用于任务调度负载均衡(load-balancing),通俗点完成自己的所有任务之后,发现其他人还有活没干完,主动(或被安排)帮他人一起干,这样达到尽早干完的目的。
1)  打印1~5
  
(1 to 5).foreach(println(_))
  
println()
  
(1 to 5).par.foreach(println(_))
  
2)  查看并行集合中元素访问的线程
  
val result1 = (0 to 10000).map{case _  => Thread.currentThread.getName}.distinct
  
val result2 = (0 to 10000).par.map{case _  => Thread.currentThread.getName}.distinct
  
println(result1)
  
println(result2)
  
5.16 操作符
这部分内容没有必要刻意去理解和记忆,语法使用的多了,自然就会产生感觉,该部分内容暂时大致了解一下即可。
1) 如果想在变量名、类名等定义中使用语法关键字(保留字),可以配合反引号反引号:
  
val `val` = 42
  
2)  这种形式叫中置操作符,A操作符B等同于A.操作符(B)
3) 后置操作符,A操作符等同于A.操作符,如果操作符定义的时候不带()则调用时不能加括号
4)  前置操作符,+-、!、~等操作符A等同于A.unary_操作符
5) 赋值操作符,A操作符=B等同于A=A操作符B

没找到任何评论,期待你打破沉寂

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条