Scala编程基础(四)-- List作业以及部分源码分析

/**
  *作业题
  */
object ListTest {
  def main(args: Array[String]): Unit = {
    //创建一个List
    val list0=List(1,7,9,8,0,3,5,4,6,2)

    //将list0中的每一个元素乘以10后生成一个新的集合
    val list1=list0.map(x=>x*10)
    println("list1==== "+list1)
    //运行结果:list1==== List(10, 70, 90, 80, 0, 30, 50, 40, 60, 20)

    //将list0中的偶数取出来生成一个新的集合
    val list2=list0.filter(x=>x%2==0)
    println("list2==== "+list2)
    //运行结果:list2==== List(8, 0, 4, 6, 2)

    //将list0排序后生成一个新的集合 --以下3种排序后结果一致
    val list3=list0.sorted
    val list4=list0.sortBy(x=>x)
    val list5=list0.sortWith((x,y)=>x<y)
    println("list3==== "+list3)
    //运行结果:list3==== List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
    println("list4==== "+list4)
    //运行结果:list4==== List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
    println("list5==== "+list5)
    //运行结果:list5==== List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

    //反转顺序
    val list6=list3.reverse
    println("list6==== "+list6)
    //运行结果:list6==== List(9, 8, 7, 6, 5, 4, 3, 2, 1, 0)

    //将list0中的元素4个一组,类型为Iterator[List[Int]]
    val list7=list0.grouped(4)
    println("list7==== "+list7)
    //运行结果:list7==== non-empty iterator

    //将Iterator转换成List
    val list8=list7.toList
    println("list8==== "+list8)
    //运行结果:list8==== List(List(1, 7, 9, 8), List(0, 3, 5, 4), List(6, 2))

    //将多个list压扁成一个List
    val list9=list8.flatten
    println("list9==== "+list9)
    //运行结果:list9==== List(1, 7, 9, 8, 0, 3, 5, 4, 6, 2)

    val lines = List("hello tom hello jerry", "hello jerry", "hello kitty")

    //先按空格切分,在压平 方法1
    lines.map(x=>x.split(" "))
    val result = lines.map(x=>x.split(" ")).flatten
    println("result==== "+result)
    //运行结果:result==== List(hello, tom, hello, jerry, hello, jerry, hello, kitty)

    //先按空格切分,在压平 方法2
    val result1=lines.flatMap(_.split(" "))
    println("result1==== "+result1)
    //运行结果:result1==== List(hello, tom, hello, jerry, hello, jerry, hello, kitty)

    //并行计算求和
    val result2=list0.par.sum
    println("result2==== "+result2)
    //运行结果:result2==== 45

    //化简:reduce
    //将非特定顺序的二元操作应用到所有元素
    val result3=list0.reduce((x,y) => x + y)
    println("result3==== "+result3)
    //运行结果:result3==== 45

    //按照特定的顺序
    //第一个下划线表示 累加之后的结果
    //第二个下划线 表示之后取出的元素
    val result4 = list0.reduceLeft(_+_)
    val result5= list0.reduceRight(_+_)
    println("result4==== "+result4)
    //运行结果:result4==== 45
    println("result5==== "+result5)
    //运行结果:result5==== 45

    //折叠:有初始值(无特定顺序) 100 + sum
    val result6 = list0.fold(100)((x,y)=>x+y)
    println("result6==== "+result6)
    //运行结果:result6==== 145

    //折叠:有初始值(有特定顺序)100 + sum
    val result7 = list0.foldLeft(100)((x,y)=>x+y)
    println("result7==== "+result7)
    //运行结果:result7==== 145

    //聚合
    val  list10= List(List(1, 2, 3), List(4, 5, 6), List(7,8), List(9,0))
    val  result8 = list10.par.aggregate(10)(_+_.sum,_+_) //多线程先求部分,在汇总计算
    println("result8==== "+result8)
    //第一次运行结果:result8==== 85
    //第二次运行结果:result8==== 85
    //第三次运行结果:result8==== 85
    //注意:虽然这里实验了3次,计算结果显示一致,但是计算结果会因为参加计算的线程个数不同,而不一致。

    //获取到参与并行计算的线程
    println(list10.par.collect{
      case _=>Thread.currentThread().getName
    }.distinct)
    //第一次运行结果:ParVector(ForkJoinPool-1-worker-13, ForkJoinPool-1-worker-11, ForkJoinPool-1-worker-9, ForkJoinPool-1-worker-7)
    //第二次运行结果:ParVector(ForkJoinPool-1-worker-15, ForkJoinPool-1-worker-13, ForkJoinPool-1-worker-1, ForkJoinPool-1-worker-9)
    //第三次运行结果:ParVector(ForkJoinPool-1-worker-13, ForkJoinPool-1-worker-9, ForkJoinPool-1-worker-11, ForkJoinPool-1-worker-5)

    val l1 = List(5,6,4,7)
    val l2 = List(1,2,3,4)
    //求并集
    val r1=l1.union(l2)
    println("r1=== "+r1)
    //运行结果:r1=== List(5, 6, 4, 7, 1, 2, 3, 4)

    //求交集
    val r2=l1.intersect(l2)
    println("r2=== "+r2)
    //运行结果:r2=== List(4)

    //求差集
    val r3=l1.diff(l2)
    println("r3=== "+r3)
    //运行结果:r3=== List(5, 6, 7)

    //reduceLeft(op), reduceLeft(op),
    //foldLeft(init)(op), foldRight(init)(op)
    //是将操作应用到同一集合的相邻元素
    val list = List(1,2,3,4,5)
    var reduce:Int = 0
    reduce = list.reduceLeft(_-_)
    println(reduce)
    //运行结果:-13  //((((1-2)-3)-4)-5)
    reduce = list.reduceRight(_-_)
    println(reduce)
    //运行结果:3  //1-(2-(3-(4-5)))
    reduce = list.foldLeft(0)(_-_)
    println(reduce)
    //运行结果:-15  //(((((0-1)-2)-3)-4)-5)
    reduce = list.foldRight(0)(_-_)
    println(reduce)
    //运行结果:3   //1-(2-(3-(4-(5-0))))
	    
  }
}

----------------------------------------源码分析--------------------------------------------------

reduce源码分析:

val list0 = List(1,2,3,4)

list0.reduce((x,y)=>x+y)  //运行结果:10    (((1+2)+3)+4)
reduceLeft
var first = true
var acc: B = 0.asInstanceOf[B] 等价于 var acc:Int = 0

for循环
第一次循环:acc=1 first=false
第二次循环:acc=op(1,2)=3
第三次循环:acc=op(3,3)=6
第四次循环:acc=op(6,4)=10

reduceRight
list.reduceRight((x,y)=>x-y)  //运行结果:-2  (1-(2-(3-4)))

if (isEmpty) throw new UnsupportedOperationException("Nil.reduceRight")
else if (tail.isEmpty) head  //只有一个元素
else op(head, tail.reduceRight(op))

op(head, tail.reduceRight(op))
    -> op(1,List(2,3,4).reduceRight(op)     //1- 3 = -2
        ->op(2,List(3,4).reduceRight(op)    //2- -1 = 3
            ->op(3,List(4).reduceRight(op)  //3- 4 = -1
                ->4
)

List(1,2,3,4).foldRight(0)(_-_) 源码分析   //运行结果:-10     ((((0-1)-2)-3)-4)

override def foldRight[B](z: B)(op: (A, B) => B): B =
    reverse.foldLeft(z)((right, left) => op(left, right))
    
List(4,3,2,1).foldLeft(z)((right, left) => op(left, right))  //运行结果:-2  (1-(2-(3-(4-0)))

def foldLeft[B](z: B)(@deprecatedName('f) op: (B, A) => B): B = {
    var acc = z
    var these = this
    while (!these.isEmpty) {
      acc = op(acc, these.head)
      these = these.tail
    }
    acc
  }
 
while循环:
第一次:acc = op(0,4) => op(4,0)=4-0=4 these=List(3,2,1)
第二次:acc = op(4,3) => op(3,4)=3-4=-1 these=List(2,1)
第三次:acc = op(-1,2) => op(2,-1)=2- -1=3 these=List(1)
第四次:acc = op(3,1) => op(1,3)=1-3=-2 these={}
最终结果-2

 

使用while打印list:
while(!list.isEmpty){
    println(list.head)
    list=list.tail
}

 

 

 

 

 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值