集合框架概述
Iterable <--------- Seq, Set, Map
Seq <--------- IndexedSeq, linkedSeq
indexedSeq <------ Vectors, Array ,String
linkedSeq <------- List
2.集合常见操作
map, flatMap, filter
foldLeft, foldRight
3. 实现Map操作
abstract class List[+T] { def map[U](f: T => U): List[U] = this match { case x :: xs => f(x) :: xs.map(f) case Nil => Nil } }
实现flatMap,只有两点不同:1.f返回的是List 2.prepend改成contact
abstract class List[+T] { def flatMap[U](f:T=>List[U]):List[U] = this match { case List(x::xs) => f(x) ++ flatMap(xs) case Nil => Nil } }
实现filter
abstract class List[+T] { def filter(f:T => Boolean): List[T] = this match { case List(x::xs) => if (f(x)) x:: xs.filter(f) else xs.filter(f) case Nil => Nil } }
filter返回类型和原List是一样的
4. ++ 和 :::的不同
package week1 object Test { List(1,2) ::: List(3,4) //> res0: List[Int] = List(1, 2, 3, 4) List(1,2) ++ List(3,4) //> res1: List[Int] = List(1, 2, 3, 4) }
:::是右操作符,执行的是prepend操作
++是左操作符,执行的是append操作
5.Scala没有for循环,只有for表达式
scala将for 表达式转化成map,flatmap或filter来执行
for (x <- e1) yield e2 被转化成 e1.map(x => e2)
for(x <- e1 if f; s) yield e2 被转化成 for (x <- e1.withFilter(x =>f); s) yield e2
6.for表达式可以与模式匹配一起用
val data: List[JSON] = ... for { JObj(bindings) <- data JSeq(phones) = bindings("phoneNumbers") JObj(phone) <- phones JStr(digits) = phone("number") if digits startsWith "212" } yield (bindings("firstName"), bindings("lastName"))
7. flatMap, map,filter到for 语句的转换。找出100以内所有 i +j 为素数的i,j组合
object Main extends App { def isPrime(n: Int):Boolean = (2 to n-1) forall (d => n %d != 0) val ls = (1 to 10) flatMap (i => (1 to 10) filter (j => isPrime(i+j)) map (j => (i, j))) println(ls) }
虽然达到了目的,可读性却很差,改用for循环
package week1 object Main extends App { def isPrime(n: Int):Boolean = (2 to n-1) forall (d => n %d != 0) val ls = for { i <- 1 to 10 j <- 1 to 10 if isPrime(i +j ) } yield (i, j) println(ls) }
8. 编译器做的转换
for (x <- e1 if f; s) yield e2 for (x <- e1.withFilter(x => f); s) yield e2 for (x <- e1; y <- e2; s) yield e3 e1.flatMap(x => for (y <- e2; s) yield e3)
带有模式匹配的for语句,模式被改写成传递给withFilter的函数
pat <- expr x <- expr withFilter { case pat => true case _ => false } map { case pat => x }