本篇特用来对Scala的日常惯用法做一些记录,尽量简洁不废话。第三方包除外,只收录标准库。
- 集合类(Seq)
- 集合类(Map)
- 正则
- JSON解析
- XML解析
- 语法糖
- 杂项
-
集合类(Seq)
- 构建
val truth = "fly" :: "is" :: "fun" :: Nil //List(fly,is,fun) val list1 = List(1,2) val list2 = List.fill(3)("one") //List[String] =List(one,one,one) val list3 = List.fill(3,2)(0) //List[List[Int]] =List(List(0,0),List(0,0),List(0,0)) val list4 = List.range(9,1,-3) //List[Int] =List(9,6,3) val list5 = truth ::: list4 //List(fly,is,fun,9,6,3) val list6 = truth ++ list4 //List(fly,is,fun,9,6,3)
- 分组
truth.groupBy(_.length == 2) //((List(is),List(fly,fun)) truth.grouped(2) //Iterator:List(fly,is),List(fun) truth.sliding(2) //Iterator:List(fly,is),List(is,fun)- 截取
truth.head //fly truth.tail //List(is,fun) truth.init //List(fly,is) truth.last //fun truth.drop(2) //List(fun) truth.dropRight(2) //List(fly) truth.takeRight(2) //List(is,fun) truth.takeWhile(_.charAt(0).toLowerCase!='I') //List(fly) truth.dropWhile(_.的charAt(0).toLowerCase!='I') //List(is,fun)- 过滤及计数
truth.filter(s => s.length == 3) //List(fly,fun) truth.find(_.charAt(0)=='A') //None truth.count(s => s.length == 3) //2- 校验
truth.isEmpty //false truth.forall(_.length> 2) //false truth.exists(_.charAt(0)=='i') //true truth.contains("is") //true truth.sameElements(List("fly","is","fun")) //true- 添加序号
truth.zipWithIndex //List((fly,0),(is,1),(fun的,2)) truth.indices zip truth //Vector((0,fly),(1,),(2,fun))- 排序
truth.sorted //List(fly,fun,is) truth.sorted(Ordering[String].reverse) //List(is,fun,fly) truth.sortBy(x =>(x.toString.length, x)) //List(is,fly,fun) truth.sortBy(x =>(x.toString.length, x))(Ordering[(Int,String)].reverse) //List(fun,fly,is) truth.sortWith(_.length - _.length < 0) //List(is,fly,fun)- 折叠
truth.foldRight("!")(_ + _) // Flyisfun! truth.reduceRight(_ + _) // Flyisfun truth.foldRight(List[String]()){(x,List)=>("<"+ x +">")::List} //List(- 连接 - 展开, , ) truth.foldLeft("is")(_ + _) //isflyisfun List(1,2,3)reduceLeft(_ + _) //6
List.concat(List(),List('b'),List('c')) //List(b,c) truth.flatMap(_.toList) //List(f, l, y, i, s, f, u, n)
-
集合类(Map)
--不可变
val map1 = Map("i" -> 1,"ii" -> 2) map1 + ("vi" -> 6) //Map(i -> 1, ii -> 2, vi -> 6) map1 - "ii" //Map(i -> 1) map1 ++ List("iii" -> 3,"v" -> 5) //Map(i -> 1, ii -> 2, iii ->3, v -> 5) map1.getOrElse("vi",6) //6
--可变
val map2 = scala.collection.mutable.Map.empty[String,Int] map2 += ("one" -> 1) //Map(one - > 1) map2 -= "one" //Map() map2 ++= Map("one" -> 1,"two" -> 2,"three" -> 3) //Map(one -> 1, three -> 3, two -> 2) map2 --= List("one","two") //Map(three -> 3) map2.getOrElseUpdate("one",100) //Map(one -> 100, three -> 3) map2.getOrElseUpdate("four",200) //Map(one -> 100, three -> 3, four -> 200) map2.transform((_,i)=> i + 1) //Map(one -> 101, three -> 4, four -> 201)
-
正则
--变量取值
val reg1 = new regex("""(\d{4})-(\d{2})-(\d{2})""") val reg2 = """(\d{4})-(\d{2})-(\d{2})""".r val reg1(year, month, day)="2016-12-13" //year:2016 month:12 day:13 "2016-12-13" match{ case reg2(year,month,day) => (year,month,day) //year:2016 month:12 day:13 case _ => prIntln("not found!") }--名称取值
val reg3 =new Regex("""(\d{4})-(\d{2})-(\d{2})""","year","month","day") reg3.findAllIn("2016-12-13 american tv 2017-11-14").foreach(println) val m1 = for (r <- reg3.findAllMatchIn("abc 2016-12-13 american tv 2017-11-14")) yield r.group("year") println(m1.toList) //List(2016, 2017)--序号取值
val m2 = for (r <- reg3.findAllMatchIn("abc 2016-12-13 american tv 2017-11-14")) yield r.group(2) println(m2.toList) //List(12, 11)
-
JSON解析
【说明】2.11以后的jar包需单独下载 https://github.com/scala/scala-parser-combinators
val jsonStr= """ {"subjects":[ {"title":"孤单又灿烂的神:鬼怪", "rate":"9.1", "id":"26761935"}, {"title":"西部世界第one季", "rate":"9.0", "id":"2338055"}] }""" //一次性使用可以用 asInstanceOf做类型转换,转换后为List,Map,和数组的混合体 val map= JSON.parseFull(jsonStr).get.asInstanceOf [Map[String,List[Map[String,String]]]] val list = (for (m <- map("subjects")) yield List(m("id"), m("title"), m("rate"))) println(list) //List(List(26761935, 孤单又灿烂的神:鬼怪, 9.1), List(2338055, 西部世界第one季, 9.0)) //需要异常处理的场合使用模式匹配 val map2 = JSON.parseFull(jsonStr) match { case m: Map[String,List[Map[String,String]]] => m case _ => //todo 异常处理如: println("解析失败:"+ jsonStr) }
-
XML解析
【说明】2.11以后的jar包需单独下载https://github.com/scala/scala-xml
--构建
val elem1 = scala.xml.XML.loadString(" ") val elem2 = scala.xml.XML.loadFile("1.XML") val (name, age)=("James",10) val elem3 = name={name},age={age} val elem4 ={(1 to 5).map(i => //{i} )}1 2 3 4 5
--节点抽取
val elem =val name1 = (elem \"u")(0)\"@name" //aa val name2 = elem \"u"\\"@name" //aa bb cc elem match{ case {uAll @ _*} => for(u <- uAll) println(u \ "@name") //aa bb cc case _ => "no match!" } val xml=(for(item <- xml\"item"; p = (item\"@price").text.toDouble; q = (item\"@quantity").text.toInt) yield (p*q)).map(println)
--XML输出
val pp = new scala.xml.PrettyPrInter(80,4) //行宽80,缩进4 prIntln(elem) //直接输出 prIntln(pp formatNodes elem) //格式化输出
-
语法糖
// 观察语法糖对理解Scala内部的实现非常必要,使用这个命令 scala -Xprint:typer test.scala
// case class 语句会自动给类中添加 equals/ hashCode/ toString/ copy/ apply/ unapply 等方法
// 特别是 apply 用于 类名() 语法生成对象(不使用new!)
// 而 unapply 用于模式匹配时项目的抽取
case class People( name: String, age: Int); val p = People("zhangshan",20) p match { case People(name,age) => println(name,age) }
// for 语句会变换成 foreach(foreache...))
// for-yield 会变换成 flatMap(flatMap(...map())) 注意最后一级为map
// for 语句中含有if 则会转换成 withFilter()调用
val (f1,f2,f3) = (Future{1}, Future{1}, Future{1}) for{ a <- f1; b <- f2; c <- f3 } yield a+b+c
// lazy变量,背后的实现是个典型的双重检测锁(DCL)模式
-
杂项
- 任意数生成
//生成[0,N)的任意数 - 同java.util.Random中 Random.nextInt(99999) //生成任意5位字母数字 Random.alphanumeric.take(5).mkString