/**
*作业题
*/
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)=>xx.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
}