Scala_Note_1
1 class 中调用类的伴生对象(object)方法时需要加类名
2 理解var&val VS mutable&immutable的区别
3 理解lazy val.若一个耗时方法被声明为lazy val,则调用该方法的所有方法尽量声明为lazy val.否则类实例化的时候,还是会计算,似的lazy val失效
4 mutable.Map can not cast to immutable.Map
5 Description Resource Path Location Type
type mismatch; found : item_id.type (with underlying type String) required: _1 UserMap.scala /TmallData/src/weejang line 68 Scala Problem
6 xml: xml 在2.11以后的系列中,都将被作为一个独立的jar引入.
refer: http://stackoverflow.com/questions/22223304/how-will-xml-modularisation-in-scala-2-11-play-with-xml-literals
7 @符号的作用:
---1
//绑定匹配变量
val list = List(User("jangwee",11),1,User("Liuhuapeng",33),4)
val seeList = for{
elem @ User(_,_) <- list
}yield (elem)
println(seeList)
//output :
// List(User(jangwee,11), User(Liuhuapeng,33))
8 sbt 拉取下来的库位置
~/.ivy/cache
9 akka 需要引入 config.jar
com.typesafe.
refer : http://stackoverflow.com/questions/26052261/bad-symbolic-reference-in-scala-ide-for-eclipse
10
过滤数据:
val wordFrequencies = ("hh", 5) :: ("ww", 2) :: ("aa", 7) :: Nil
//method1,Tuple2
def format1(wf: Seq[(String, Int)]): Seq[String] = {
wf.filter { x => x._2 > 2 && x._2 < 7 }.map { _._1 }
}
println(format1(wordFrequencies))//List(hh)
//method2,模式匹配结构
def format2(wf: Seq[(String, Int)]): Seq[String] = {
wf.filter { case (word, count) => count > 2 && count < 7 }.map { case (word, _) => word }
}
println(format2(wordFrequencies))//List(hh)
//method3-1,偏函数
// val pf : PartialFunction[(String,Int),String] = {
// case (word,freq) if freq > 2 && freq < 7 => word
// }
//method3-2,显式定义偏函数Trait
val pf = new PartialFunction[(String, Int), String] {
def apply(wordFrequency: (String, Int)): String = {
wordFrequency match {
case (word, count) if count > 2 && count < 7 => word
}
}
def isDefinedAt(wordFrequency: (String, Int)): Boolean = {
wordFrequency match {
case (word, count) if count > 2 && count < 7 => true
case _ => false
}
}
}
// Compile Okay,RunTime Error
// Exception in thread "main" scala.MatchError: (ww,2) (of class scala.Tuple2)
//println(wordFrequencies.map(pf))
println(wordFrequencies.map(pf.isDefinedAt(_))) //List(true, false, false)
println(wordFrequencies.collect(pf)) // List(hh)
11 for-expression
val lastNames = List("Jang", "Geng")
val firstNames = List("Wee", "Jie")
//for-expression
val allName = for {
lastname <- lastNames
firstname <- firstNames
} yield lastname + " " + firstname
println(allName) //List(Jang Wee, Jang Jie, Geng Wee, Geng Jie)
// == flatMap
val allName2 = lastNames.flatMap { lastname =>
firstNames.map { firstname => lastname + " " + firstname }
}
println(allName2) //List(Jang Wee, Jang Jie, Geng Wee, Geng Jie)
// why flatMap ? what happened with Map?
val allName3 = lastNames.map { lastname =>
firstNames.map { firstname => lastname + " " + firstname }
}
println(allName3) //List(List(Jang Wee, Jang Jie), List(Geng Wee, Geng Jie))
// with Option
val maybeFirstName = Some("Wee")
val maybeLastName = None
val result = for{
lastname <- maybeLastName
firstname <- maybeFirstName
} yield User(lastname,firstname)
println(result) // None
12 异常处理
//类Java方式的异常处理
case class Customer(age: Int)
class Cigarettes
case class UnderAgeException(message: String) extends Exception(message)
object MMain {
def main(args: Array[String]): Unit = {
val customer = new Customer(16)
try{
buyCigarettes(customer)
}catch{
//case UnderAgeException(msg) => println(msg) //Customer must be older than 18 but was 16
case ex @ UnderAgeException(_) => ex.printStackTrace()
// qoeAnalyzer.UnderAgeException: Customer must be older than 18 but was 16
// at qoeAnalyzer.MMain$.buyCigarettes(MMain.scala:35)
// at qoeAnalyzer.MMain$.main(MMain.scala:25)
// at qoeAnalyzer.MMain.main(MMain.scala)
}
}
def buyCigarettes(customer: Customer) : Cigarettes = {
if (customer.age < 18 )
throw UnderAgeException(s"Customer must be older than 18 but was ${customer.age}")
else
new Cigarettes
}
}
// 函数式的错误处理 -Try
import scala.util.Random
import scala.util.{ Try,Success, Failure }
import scala.io.StdIn
object MMain {
def main(args: Array[String]): Unit = {
val result = divide
result match {
case Success(v) =>
println(s"result of is ${v}")
case Failure(e) =>
println("You must've divided by zero or entered something that's not an Int. Try again!")
println(e.getMessage)
}
}
def divide: Try[Int] = {
val dividend = Try(StdIn.readLine("Enter an Int that you'd like to divide:\n").toInt)
val divisor = Try(StdIn.readLine("Enter an Int that you'd like to divide by :\n").toInt)
//Method_1: for-expression
// val problem = for{
// x <- dividend
// y <- divisor
// } yield( x / y )
//Method_2: flatMap*N-Map
val problem = dividend.flatMap( x => divisor.map { y => (x / y) })
problem
}
}
:output:
Enter an Int that you'd like to divide:
10
Enter an Int that you'd like to divide by :
3
result of is 3
or
Enter an Int that you'd like to divide:
10
Enter an Int that you'd like to divide by :
0
You must've divided by zero or entered something that's not an Int. Try again!
/ by zero
----
def main(args: Array[String]): Unit = {
def parseURL(url:String) = Try(new URL(url))//MalformedURLException
//val url = parseURL(StdIn.readLine("URL: ")) getOrElse new URL("http://www.baidu.com")
val result1 = parseURL("http://www.baidu.com").map{_.getProtocol} //Success(http)
result1.map { println _ }
val result2 = parseURL("garbage").map{_.getProtocol} //Failure(java.net.MalformedURLException: no protocol: garbage)
result2.map { println _ }
}
output:
http
:result2不执行里面的闭包
----
def main(args: Array[String]): Unit = {
def parseURL(url: String) = Try(new URL(url)) //MalformedURLException
//Method1 -(flatMap with Map)
def getURLContent1(url: String):Try[Iterator[String]] = {
parseURL(url).flatMap { url => Try(url.openConnection) }
.flatMap { conn => Try(conn.getInputStream) }
.flatMap { istream => Try(scala.io.Source.fromInputStream(istream))}
}.map{_.getLines()}
getURLContent1("http://www.baidu.com").map{ x => x.foreach { println _} }
//Method2 - for express
def getURLContent2(url: String): Try[Iterator[String]] = for{
purl <- parseURL(url)
conn <- Try(purl.openConnection)
inputStream <- Try(conn.getInputStream)
source <- Try(scala.io.Source.fromInputStream(inputStream))
} yield source.getLines()
getURLContent2("http://www.baidu.com").map{ x => x.foreach { println _} }
}
----
添加 recover
//添加故障回复 recover
val content = getURLContent1("garbage") recover {
case e: FileNotFoundException => Iterator("Requested page does not exist")
case e: MalformedURLException => Iterator("Please make sure to enter a valid URL")
case _ => Iterator("An unexpected error has occurred. We are so sorry!")
}
content.get.foreach { println _ }
---
13 Either - 无偏的Try
import java.net.URL
import scala.io.Source
def getContent(url: URL): Either[String,Source] = {
if(url.getHost.contains("google"))
Left("Requested URL is blocked for the good of the people")
else
Right(Source.fromURL(url))
}
//RightProjection
val content : Either[String,Iterator[String]] = getContent(new URL("http://www.baidu.com")).right.map { _.getLines }
//Right(non-empty iterator)
val morecontent : Either[String,Iterator[String]] = getContent(new URL("http://google.com")).right.map{ _.getLines }
//Left(Requested URL is blocked for the good of the people)
//LeftProjection
val content1 : Either[Iterator[String],Source] = getContent(new URL("http://www.baidu.com")).left.map{ Iterator(_) }
//Right(non-empty iterator)
val morecontent1 : Either[Iterator[String],Source] =getContent(new URL("http://google.com")).left.map{ Iterator(_) }
//Left(non-empty iterator)
//content.right.map{ iter => iter.foreach { println _ } }
// 网页内容 ...content-type" content="text/html;charset ...
//morecontent.right.map{ iter => iter.foreach { println _ } }
//无输出
content1.left.map { iter => iter.foreach { println _ } }
//无输出
morecontent1.left.map { iter => iter.foreach {println _}}
//Requested URL is blocked for the good of the people
----
val baidu = new URL("http://www.baidu.com")
val gufen = new URL("http://www.gfsoso.net")
// Method 1
// val contentSize = getContent(baidu).right.flatMap{
// bd => getContent(sina).right.map{
// sn => ( bd.getLines().size , sn.getLines().size )
// }
// }
// Method 2 For-comprehesion
val contentSize = for{
bd <- getContent(baidu).right
gf <- getContent(gufen).right
line1 <- Right(bd.getLines().size).right
line2 <- Right(gf.getLines().size).right
}yield (line1,line2)
println(contentSize) //Right((23,129))
----
//Fold 函数
//如果想变换一个Either(不论它是Left值,还是Right值),可以使用定义在Either上的fold方法.这个方法接受两个
//返回相同类型的变换函数,当这个函数是Left值时,第一个函数被调用,否则,第二个函数会被调用
//替换模式匹配
val content: Iterator[String] = getContent(new URL("http://www.baidu.com")).fold(Iterator(_), _.getLines())
----
//异常处理
import scala.util.control.Exception.catching
def handling[Ex <: Throwable, T](exType: Class[Ex])(block: => T): Either[Ex, T] =
catching(exType).either(block).asInstanceOf[Either[Ex, T]]
def parseURL(url: String): Either[MalformedURLException, URL] =
handling(classOf[MalformedURLException])(new URL(url))
----
处理集合
object MMain {
type Citizen = String
case class BlackListResource(url: URL, visitor: Set[Citizen])
val blacklist = List(
BlackListResource(new URL("https://google.com"),Set("hh")),
BlackListResource(new URL("https://sina.com"),Set.empty),
BlackListResource(new URL("https://git.com"),Set.empty),
BlackListResource(new URL("https://finger.com"),Set("ni","wo"))
)
def main(args: Array[String]): Unit = {
val checkedList : List[Either[URL,Set[Citizen]]] = blacklist.map { bsource =>
if(bsource.visitor.isEmpty) Left(bsource.url)
else Right(bsource.visitor)
}
val suspicisousResources = checkedList.flatMap(_.left.toOption)
val problemCitizens = checkedList.flatMap(_.right.toOption)
println(problemCitizens.flatten.toSet)
}
---------
高阶函数-DRY(Dont Repeat Yourself)
// 命名
type EmailFilter = Email => Boolean
//
def newEmailsForUser(mails:Seq[Email],filter: EmailFilter) = mails.filter(filter)
//EmailFilter工厂函数
val sendByOneOf:Set[String] => EmailFilter =
(senders: Set[String] ) =>
(email: Email) =>
senders.contains(email.sender)
val notSendByOneOf:Set[String] => EmailFilter =
(senders: Set[String]) =>
(email: Email) =>
!senders.contains(email.sender)
val minumSize : Int => EmailFilter =
(n: Int) =>
(email: Email) =>
email.text.size > n
val maxnumSize : Int => EmailFilter =
(n: Int) =>
(email: Email) =>
email.text.size < n
def main(args: Array[String]): Unit = {
val emailFilter: EmailFilter = notSendByOneOf(Set("jangwee1@sina.com.cn"))
val emails = Email(
subject = "hello",
text = "hello",
sender = "jangwee1@sina.com.cn",
recipient = "hh"
) :: Nil
val result = newEmailsForUser(emails,emailFilter)
println(result.toSeq.toString()) //List()
}
improve:
type sizeCheck = Int => Boolean
val sizeConstraint:sizeCheck => EmailFilter =
(f: sizeCheck) =>
(email: Email) =>
f(email.text.size)
val mininumSize: Int => EmailFilter =
(n: Int) =>
sizeConstraint(_ > n)
val maxinumSize: Int => EmailFilter =
(n: Int) =>
sizeConstraint(_ < n)