在最开始处引入 log 相关的 包
import org.apache.log4j.{Logger,Level} 在需要屏蔽日志输出的地方加上这两行代码
// 屏蔽不必要的日志显示在终端上
Logger.getLogger("org.apache.spark").setLevel(Level.ERROR)
Logger.getLogger("org.eclipse.jetty.server").setLevel(Level.OFF) // scala io Case 类与匹配模式示例
package com.converter
import java.io.PrintWriter import scala.io.Source
case class ICD(code:String,icdValue:Int)
object Demo { def main(args:Array[String]):Unit={
println(apply("FrankLi","gmail"))
println(unapply("FrankLi@gmail"))
println(unapply("FrankLigmail")) // scala io 读取文件并进行操作
val strIt=
Source.fromFile("input/icd")
.getLines()
.map{line =>
val sb = new StringBuffer
val cols = line.split(",",-1)
ICD(cols(0),cols(1).toInt)
sb.append(cols(0))
.append("|")
.append(cols(1))
sb.toString
}
val writer = new PrintWriter("input/convertedICD.txt")
for(str <- strIt){
writer.write(str)
writer.write("\r\n")
// writer.flush()
}
writer.close();
// .foreach(println)
}
def apply(userName:String,domain:String):String={
userName+"@"+domain
}
@throws(classOf[NumberFormatException])
def unapply(emailAddress:String):Option[(String,String)]={
val parts = emailAddress.split("@")
if(parts.length == 2){
Some((parts(0),parts(1)))
}
else
None
}
} //提取器 unapply , apply package com.converter object Demo { def main(args:Array[String]):Unit={
println(apply("FrankLi","gmail"))
println(unapply("FrankLi@gmail"))
println(unapply("FrankLigmail"))
}
def apply(userName:String,domain:String):String={
userName+"@"+domain
}
def unapply(emailAddress:String):Option[(String,String)]={
val parts = emailAddress.split("@")
if(parts.length == 2){
Some((parts(0),parts(1)))
}
else
None
}
} // scala 基础函数 val testList=(1 to 10) println("testListRes: "+testList.fold(0)((base,n) => base+n)) println("testListRes: "+testList.foldRight(0)((base,n) => base+n)) foldLeft , foldRight
整体替换, 迭代 val str = "abc"
println("strSub: "+str.substring(1,2)) subString 包含左边界不包含右边界
(角标从 0 开始算) hcc 是个 int
val hccStr:String=String.valueOf(hcc) Scala是数据挖掘算法领域最有力的编程语言之一,语言本身是面向函数,这也符合了数据挖掘算法的常用场景:在原始数据集上应用一系列的变换,语言本身也对集合操作提供了众多强大的函数,本文将以List类型为例子,介绍常见的集合变换操作。
一、常用操作符(操作符其实也是函数)
++ ++[B](that: GenTraversableOnce[B]): List[B] 从列表的尾部添加另外一个列表
++: ++:[B >: A, That](that: collection.Traversable[B])(implicit bf: CanBuildFrom[List[A], B, That]): That 在列表的头部添加一个列表
+: +:(elem: A): List[A] 在列表的头部添加一个元素
:+ :+(elem: A): List[A] 在列表的尾部添加一个元素
:: ::(x: A): List[A] 在列表的头部添加一个元素
::: :::(prefix: List[A]): List[A] 在列表的头部添加另外一个列表
:\ :[B](z: B)(op: (A, B) ⇒ B): B 与foldRight等价
val left = List(1,2,3)
val right = List(4,5,6) //以下操作等价
left ++ right // List(1,2,3,4,5,6)
left ++: right // List(1,2,3,4,5,6)
right.++:(left) // List(1,2,3,4,5,6)
right.:::(left) // List(1,2,3,4,5,6) //以下操作等价
0 +: left //List(0,1,2,3)
left.+:(0) //List(0,1,2,3) //以下操作等价
left :+ 4 //List(1,2,3,4)
left.:+(4) //List(1,2,3,4) //以下操作等价
0 :: left //List(0,1,2,3)
left.::(0) //List(0,1,2,3) 看到这里大家应该跟我一样有一点晕吧,怎么这么多奇怪的操作符,这里给大家一个提示,任何以冒号结果的操作符,都是右绑定的,即 0 :: List(1,2,3) = List(1,2,3).::(0) = List(0,1,2,3) 从这里可以看出操作::其实是右边List的操作符,而非左边Int类型的操作符
二、常用变换操作
1.map
map[B](f: (A) ⇒ B): List[B]
定义一个变换,把该变换应用到列表的每个元素中,原列表不变,返回一个新的列表数据
Example1 平方变换
val nums = List(1,2,3)
val square = (x: Int) => x*x
val squareNums1 = nums.map(num => num*num) //List(1,4,9)
val squareNums2 = nums.map(math.pow(_,2)) //List(1,4,9)
val squareNums3 = nums.map(square) //List(1,4,9)
1
2
3
4
5
Example2 保存文本数据中的某几列
val text = List("Homeway,25,Male","XSDYM,23,Female")
val usersList = text.map(_.split(",")(0))
val usersWithAgeList = text.map(line => {
val fields = line.split(",")
val user = fields(0)
val age = fields(1).toInt
(user,age)
}) 1
2
3
4
5
6
7
8
9
2.flatMap, flatten
flatten: flatten[B]: List[B] 对列表的列表进行平坦化操作 flatMap: flatMap[B](f: (A) ⇒ GenTraversableOnce[B]): List[B] map之后对结果进行flatten
定义一个变换f, 把f应用列表的每个元素中,每个f返回一个列表,最终把所有列表连结起来。
val text = List("A,B,C","D,E,F")
val textMapped = text.map(_.split(",").toList) // List(List("A","B","C"),List("D","E","F"))
val textFlattened = textMapped.flatten // List("A","B","C","D","E","F")
val textFlatMapped = text.flatMap(_.split(",").toList) // List("A","B","C","D","E","F") 1
2
3
4
5
3.reduce
reduce[A1 >: A](op: (A1, A1) ⇒ A1): A1
定义一个变换f, f把两个列表的元素合成一个,遍历列表,最终把列表合并成单一元素
Example 列表求和 val nums = List(1,2,3)
val sum1 = nums.reduce((a,b) => a+b) //
val sum2 = nums.reduce(_+_) //
val sum3 = nums.sum // 1
2
3
4
5
6
4.reduceLeft,reduceRight
reduceLeft: reduceLeft[B >: A](f: (B, A) ⇒ B): B
reduceRight: reduceRight[B >: A](op: (A, B) ⇒ B): B
reduceLeft从列表的左边往右边应用reduce函数,reduceRight从列表的右边往左边应用reduce函数
Example val nums = List(2.0,2.0,3.0)
val resultLeftReduce = nums.reduceLeft(math.pow) // = pow( pow(2.0,2.0) , 3.0) = 64.0
val resultRightReduce = nums.reduceRight(math.pow) // = pow(2.0, pow(2.0,3.0)) = 256.0 1
2
3
4
5
5.fold,foldLeft,foldRight
fold: fold[A1 >: A](z: A1)(op: (A1, A1) ⇒ A1): A1 带有初始值的reduce,从一个初始值开始,从左向右将两个元素合并成一个,最终把列表合并成单一元素。
foldLeft: foldLeft[B](z: B)(f: (B, A) ⇒ B): B 带有初始值的reduceLeft
foldRight: foldRight[B](z: B)(op: (A, B) ⇒ B): B 带有初始值的reduceRight val nums = List(2,3,4)
val sum = nums.fold(1)(_+_) // = 1+2+3+4 = 9 val nums = List(2.0,3.0)
val result1 = nums.foldLeft(4.0)(math.pow) // = pow(pow(4.0,2.0),3.0) = 4096
val result2 = nums.foldRight(1.0)(math.pow) // = pow(1.0,pow(2.0,3.0)) = 8.0 1
2
3
4
5
6
7
8
6.sortBy,sortWith,sorted
sortBy: sortBy[B](f: (A) ⇒ B)(implicit ord: math.Ordering[B]): List[A] 按照应用函数f之后产生的元素进行排序
sorted: sorted[B >: A](implicit ord: math.Ordering[B]): List[A] 按照元素自身进行排序
sortWith: sortWith(lt: (A, A) ⇒ Boolean): List[A] 使用自定义的比较函数进行排序
val nums = List(1,3,2,4)
val sorted = nums.sorted //List(1,2,3,4) val users = List(("HomeWay",25),("XSDYM",23))
val sortedByAge = users.sortBy{case(user,age) => age} //List(("XSDYM",23),("HomeWay",25))
val sortedWith = users.sortWith{case(user1,user2) => user1._2 < user2._2} //List(("XSDYM",23),("HomeWay",25)) 1
2
3
4
5
6
7
7.filter, filterNot
filter: filter(p: (A) ⇒ Boolean): List[A]
filterNot: filterNot(p: (A) ⇒ Boolean): List[A]
filter 保留列表中符合条件p的列表元素 , filterNot,保留列表中不符合条件p的列表元素
val nums = List(1,2,3,4)
val odd = nums.filter( _ % 2 != 0) // List(1,3)
val even = nums.filterNot( _ % 2 != 0) // List(2,4) 1
2
3
4
8.count
count(p: (A) ⇒ Boolean): Int
计算列表中所有满足条件p的元素的个数,等价于 filter(p).length
val nums = List(-1,-2,0,1,2) val plusCnt1 = nums.count( > 0) val plusCnt2 = nums.filter( > 0).length
9. diff, union, intersect
diff:diff(that: collection.Seq[A]): List[A] 保存列表中那些不在另外一个列表中的元素,即从集合中减去与另外一个集合的交集
union : union(that: collection.Seq[A]): List[A] 与另外一个列表进行连结
intersect: intersect(that: collection.Seq[A]): List[A] 与另外一个集合的交集
val nums1 = List(1,2,3)
val nums2 = List(2,3,4)
val diff1 = nums1 diff nums2 // List(1)
val diff2 = nums2.diff(num1) // List(4)
val union1 = nums1 union nums2 // List(1,2,3,2,3,4)
val union2 = nums2 ++ nums1 // List(2,3,4,1,2,3)
val intersection = nums1 intersect nums2 //List(2,3)
1
2
3
4
5
6
7
10.distinct
distinct: List[A] 保留列表中非重复的元素,相同的元素只会被保留一次
val list = List("A","B","C","A","B") val distincted = list.distinct // List("A","B","C")
1
11.groupBy, grouped
groupBy : groupBy[K](f: (A) ⇒ K): Map[K, List[A]] 将列表进行分组,分组的依据是应用f在元素上后产生的新元素
grouped: grouped(size: Int): Iterator[List[A]] 按列表按照固定的大小进行分组
val data = List(("HomeWay","Male"),("XSDYM","Femail"),("Mr.Wang","Male"))
val group1 = data.groupBy(_._2) // = Map("Male" -> List(("HomeWay","Male"),("Mr.Wang","Male")),"Female" -> List(("XSDYM","Femail")))
val group2 = data.groupBy{case (name,sex) => sex} // = Map("Male" -> List(("HomeWay","Male"),("Mr.Wang","Male")),"Female" -> List(("XSDYM","Femail")))
val fixSizeGroup = data.grouped(2).toList // = Map("Male" -> List(("HomeWay","Male"),("XSDYM","Femail")),"Female" -> List(("Mr.Wang","Male"))) 12.scan
scan[B >: A, That](z: B)(op: (B, B) ⇒ B)(implicit cbf: CanBuildFrom[List[A], B, That]): That
由一个初始值开始,从左向右,进行积累的op操作,这个比较难解释,具体的看例子吧。
val nums = List(1,2,3)
val result = nums.scan(10)(_+_) // List(10,10+1,10+1+2,10+1+2+3) = List(10,11,12,13)
1
2
13.scanLeft,scanRight
scanLeft: scanLeft[B, That](z: B)(op: (B, A) ⇒ B)(implicit bf: CanBuildFrom[List[A], B, That]): That
scanRight: scanRight[B, That](z: B)(op: (A, B) ⇒ B)(implicit bf: CanBuildFrom[List[A], B, That]): That
scanLeft: 从左向右进行scan函数的操作,scanRight:从右向左进行scan函数的操作
val nums = List(1.0,2.0,3.0)
val result = nums.scanLeft(2.0)(math.pow) // List(2.0,pow(2.0,1.0), pow(pow(2.0,1.0),2.0),pow(pow(pow(2.0,1.0),2.0),3.0) = List(2.0,2.0,4.0,64.0)
val result = nums.scanRight(2.0)(math.pow) // List(2.0,pow(3.0,2.0), pow(2.0,pow(3.0,2.0)), pow(1.0,pow(2.0,pow(3.0,2.0))) = List(1.0,512.0,9.0,2.0)
1
2
3
14.take,takeRight,takeWhile
take : takeRight(n: Int): List[A] 提取列表的前n个元素 takeRight: takeRight(n: Int): List[A] 提取列表的最后n个元素 takeWhile: takeWhile(p: (A) ⇒ Boolean): List[A] 从左向右提取列表的元素,直到条件p不成立
val nums = List(1,1,1,1,4,4,4,4)
val left = nums.take(4) // List(1,1,1,1)
val right = nums.takeRight(4) // List(4,4,4,4)
val headNums = nums.takeWhile( _ == nums.head) // List(1,1,1,1)
1
2
3
4
15.drop,dropRight,dropWhile
drop: drop(n: Int): List[A] 丢弃前n个元素,返回剩下的元素 dropRight: dropRight(n: Int): List[A] 丢弃最后n个元素,返回剩下的元素 dropWhile: dropWhile(p: (A) ⇒ Boolean): List[A] 从左向右丢弃元素,直到条件p不成立
val nums = List(1,1,1,1,4,4,4,4)
val left = nums.drop(4) // List(4,4,4,4)
val right = nums.dropRight(4) // List(1,1,1,1)
val tailNums = nums.dropWhile( _ == nums.head) // List(4,4,4,4)
1
2
3
4
16.span, splitAt, partition
span : span(p: (A) ⇒ Boolean): (List[A], List[A]) 从左向右应用条件p进行判断,直到条件p不成立,此时将列表分为两个列表
splitAt: splitAt(n: Int): (List[A], List[A]) 将列表分为前n个,与,剩下的部分
partition: partition(p: (A) ⇒ Boolean): (List[A], List[A]) 将列表分为两部分,第一部分为满足条件p的元素,第二部分为不满足条件p的元素
val nums = List(1,1,1,2,3,2,1)
val (prefix,suffix) = nums.span( _ == 1) // prefix = List(1,1,1), suffix = List(2,3,2,1)
val (prefix,suffix) = nums.splitAt(3) // prefix = List(1,1,1), suffix = List(2,3,2,1)
val (prefix,suffix) = nums.partition( _ == 1) // prefix = List(1,1,1,1), suffix = List(2,3,2)
1
2
3
4
17.padTo
padTo(len: Int, elem: A): List[A]
将列表扩展到指定长度,长度不够的时候,使用elem进行填充,否则不做任何操作。
val nums = List(1,1,1)
val padded = nums.padTo(6,2) // List(1,1,1,2,2,2)
1
2
18.combinations,permutations
combinations: combinations(n: Int): Iterator[List[A]] 取列表中的n个元素进行组合,返回不重复的组合列表,结果一个迭代器
permutations: permutations: Iterator[List[A]] 对列表中的元素进行排列,返回不重得的排列列表,结果是一个迭代器
val nums = List(1,1,3)
val combinations = nums.combinations(2).toList //List(List(1,1),List(1,3))
val permutations = nums.permutations.toList // List(List(1,1,3),List(1,3,1),List(3,1,1))
1
2
3
19.zip, zipAll, zipWithIndex, unzip,unzip3
zip: zip[B](that: GenIterable[B]): List[(A, B)] 与另外一个列表进行拉链操作,将对应位置的元素组成一个pair,返回的列表长度为两个列表中短的那个
zipAll: zipAll[B](that: collection.Iterable[B], thisElem: A, thatElem: B): List[(A, B)] 与另外一个列表进行拉链操作,将对应位置的元素组成一个pair,若列表长度不一致,自身列表比较短的话使用thisElem进行填充,对方列表较短的话使用thatElem进行填充
zipWithIndex:zipWithIndex: List[(A, Int)] 将列表元素与其索引进行拉链操作,组成一个pair
unzip: unzip[A1, A2](implicit asPair: (A) ⇒ (A1, A2)): (List[A1], List[A2]) 解开拉链操作
unzip3: unzip3[A1, A2, A3](implicit asTriple: (A) ⇒ (A1, A2, A3)): (List[A1], List[A2], List[A3]) 3个元素的解拉链操作
val alphabet = List("A",B","C")
val nums = List(1,2)
val zipped = alphabet zip nums // List(("A",1),("B",2))
val zippedAll = alphabet.zipAll(nums,"*",-1) // List(("A",1),("B",2),("C",-1))
val zippedIndex = alphabet.zipWithIndex // List(("A",0),("B",1),("C",3))
val (list1,list2) = zipped.unzip // list1 = List("A","B"), list2 = List(1,2)
val (l1,l2,l3) = List((1, "one", '1'),(2, "two", '2'),(3, "three", '3')).unzip3 // l1=List(1,2,3),l2=List("one","two","three"),l3=List('1','2','3')
1
2
3
4
5
6
7
20.slice
slice(from: Int, until: Int): List[A] 提取列表中从位置from到位置until(不含该位置)的元素列表
val nums = List(1,2,3,4,5)
val sliced = nums.slice(2,4) //List(3,4)
1
2
21.sliding
sliding(size: Int, step: Int): Iterator[List[A]] 将列表按照固定大小size进行分组,步进为step,step默认为1,返回结果为迭代器
val nums = List(1,1,2,2,3,3,4,4)
val groupStep2 = nums.sliding(2,2).toList //List(List(1,1),List(2,2),List(3,3),List(4,4))
val groupStep1 = nums.sliding(2).toList //List(List(1,1),List(1,2),List(2,2),List(2,3),List(3,3),List(3,4),List(4,4))
1
2
3
22.updated
updated(index: Int, elem: A): List[A] 对列表中的某个元素进行更新操作
val nums = List(1,2,3,3)
val fixed = nums.updated(3,4) // List(1,2,3,4)
import scala.collection.immutable.StringLike
format(args: Any*)使用本地语言环境
formatLocal(l: Locale, args: Any*)使用指定的语言环境 数据类型到字符串的转换
转  换  符 说    明  示    例
%s 字符串类型 "wwx"
%c 字符类型 'w'
%b 布尔类型 true
%d 整数类型(十进制) 99
%x 整数类型(十六进制) FF
%o 整数类型(八进制) 77
%f 浮点类型 99.99
%a 十六进制浮点类型 FF.35AE
%e 指数类型 9.668e+5
%g 通用浮点类型(f和e类型中较短的)  
%h 散列码  
%% 百分比类型 %
%n 换行符  
%tx 日期与时间类型(x代表不同的日期与时间转换符     
搭配转换符的标志
标    志 说    明 示    例 结    果
+ 为正数或者负数添加符号 ("%+d",112) +112
− 左对齐 ("%-5d",112) |112   |
0 数字前面补0 ("%05d", 99) 00099
空格 在整数之前添加指定数量的空格 ("% 5d", 99) |   99|
, 以“,”对数字分组 ("%,f", 9999.99) 9,999.990000
( 使用括号包含负数 ("%(f", -99.99) (99.990000)
# 如果是浮点数则包含小数点,如果是16进制或8进制则添加0x或0 ("%#x", 99)("%#o", 99) 0x630143
<  格式化前一个转换符所描述的参数 ("%f和%<3.2f", 99.45) 99.450000和99.45
$ 被格式化的参数索引 ("%1s", 89,"abc") 89,abc %[argument_index$][flags][width][.precision]conversion
argument_index: 可选,表明参数在参数列表中的位置。第一个参数由 "1 引用,第二个参数由 " 引用,依此类推。
flags: 可选,用来控制输出格式
width: 可选,是一个正整数,表示输出的最小长度
precision:可选,用来限定输出字符数,精度
conversion:必须,用来表示如何格式化参数的字符 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 scala> "%1$s-%2$s-%3$s".format("spark","scala","ml")res29: String = spark-scala-ml   // 百分比scala> "%d%%".format(86)res31: String = 86%   // 精度为3,长度为8scala>  "%8.3f".format(11.56789)res36: String = "  11.568"  scala>   "%8.3f".format(11.56789).length()res37: Int = 8    // 精度为3,长度为8,不足的用0填补scala> "%08.3f".format(11.56789)res38: String = 0011.568    // 长度为9,不足的用0填补scala>  "%09d".format(11)res23: String = 000000011    scala> "%.2f".format(11.23456)res25: String = 11.23     scala> val wx=36.6789wx: Double = 36.6789   scala> f"${wx}%.2f"res39: String = 36.68 //###############scala> val name="scala"name: String = scala   scala> s"spark,$name"res40: String = spark,scala   scala> "spark,$name"res41: String = spark,$name   scala> s"spark\n$name"res42: String =sparkscala   scala> "spark\n$name"res43: String =spark$name   scala> raw"spark\n$name"res44: String = spark\nscala

  

Scala中的String.split函数
http://www.cnblogs.com/davidhaslanda/p/4050471.html http://swiftlet.net/archives/709 本篇博文将详细解释scala中String.split的参数及用法。
因为scala中的String复用了Java的String,因此这也是Java中String.split的用法。
split函数主要有两种参数形式:
def split(arg0: String): Array[String]
def split(arg0: String, arg1: Int): Array[String]
我们可以将第一种参数形式看作是默认arg1=0的第二种形式,即调用split(StrToSplit)等同于调用了split(StrToSplit, 0)。因此,我将主要介绍第二种参数形式。第二种参数形式中每个参数的意义如下:
arg0: String 是一个正则表达式,代表分割的边界。这个正则表达式成功匹配一次,split的结果中就会加入一个新的子串。子串包含上次匹配后(如果没有上次匹配就是被分割字符串的起始位置)到这次匹配前的所有字符。最后,split函数会将最后一次匹配后剩余的字串作为最后一个子串加入到结果中。
arg1: Int 是对分割后子串的个数的限定。理解这个参数才能正确的运用split函数。
  当arg1大于0时,它限制arg0最多成功匹配arg1-1次,也就是说字符串最多被分成arg1个子串。此时split会保留分割出的空字符串(当两个arg0连续匹配或者arg0在头尾匹配,会产生空字符串),直到达到匹配上限。比如: 1 scala> "a-b-c".split("-", 2)
2 res38: Array[String] = Array(a, b-c)
3
4 scala> "a-b-c".split("-", 4)
5 res39: Array[String] = Array(a, b, c)
6
7 scala> "-a-b-c--".split("-", 3)
8 res40: Array[String] = Array("", a, b-c--)
9
10 scala> "-a-b-c--".split("-", 6)
11 res41: Array[String] = Array("", a, b, c, "", "")
12
13 scala> "-a-b-c--".split("-", 5)
14 res42: Array[String] = Array("", a, b, c, -)
15
16 scala> "-a-b-c--".split("-", 8)
17 res43: Array[String] = Array("", a, b, c, "", "")   当arg1等于0时,split函数会尽可能多的匹配arg0,但不再保留处于末尾位置的空字符串(这里的一个特殊情况是,当被分割字符串是一个空字符串时,分割结果仍是一个空字符串组成的数组)。比如: 1 scala> "a-b-c".split("-", 0)
2 res48: Array[String] = Array(a, b, c)
3
4 scala> "a-b-c---".split("-", 0)
5 res49: Array[String] = Array(a, b, c)
6
7 scala> "-a--b--c---".split("-", 0)
8 res50: Array[String] = Array("", a, "", b, "", c)
9
10 scala> "".split("-", 0)
11 res51: Array[String] = Array("")   当arg1小于0时,split函数会尽可能多的匹配arg0,并且保留末尾的空字符串。比如:
1 scala> "a-b-c".split("-", -1)
2 res52: Array[String] = Array(a, b, c)
3
4 scala> "-a--b--c-".split("-", -1)
5 res53: Array[String] = Array("", a, "", b, "", c, "") 在java.lang包中有String.split()方法的原型是:
public String[] split(String regex, int limit)
split函数是用于使用特定的切割符(regex)来分隔字符串成一个字符串数组,函数返回是一个数组。在其中每个出现regex的位置都要进行分解。
需要注意是有以下几点:
(1)regex是可选项。字符串或正则表达式对象,它标识了分隔字符串时使用的是一个还是多个字符。如果忽略该选项,返回包含整个字符串的单一元素数组。
(2)limit也是可选项。该值用来限制返回数组中的元素个数。
(3)要注意转义字符:“.”和“|”都是转义字符,必须得加"\\"。同理:*和+也是如此的。
如果用“.”作为分隔的话,必须是如下写法:
String.split("\\."),这样才能正确的分隔开,不能用String.split(".");
如果用“|”作为分隔的话,必须是如下写法:
String.split("\\|"),这样才能正确的分隔开,不能用String.split("|");
(4)如果在一个字符串中有多个分隔符,可以用“|”作为连字符,比如:“acountId=? and act_id =? or extra=?”,把三个都分隔出来,可以用
String.split("and|or");
(5)split函数结果与regex密切相关,常见的几种情况如下所示:
1234567891011121314151617181920212223242526272829303132333435 public class SplitTest {public static void main(String[] args) {String str1 = "a-b"; String str2 = "a-b-";String str3 = "-a-b";String str4 = "-a-b-";String str5 = "a";String str6 = "-";String str7 = "--";String str8 = "";split(str1);split(str2);split(str3);split(str4);split(str5);split(str6);split(str7);split(str8);}public static void split(String demo){String[] array = demo.split("-");int len = array.length;System.out.print("\"" + demo + "\" 分割后的长度为:" + len);if(len >= 0){System.out.print(",分割后的结果为:");for(int i=0; i<len; i++){System.out.print(" \""+array[i]+"\"");} }System.out.println();}}
运行结果为:
"a-b" 分割后的长度为:2,分割后的结果为: "a" "b"
"a-b-" 分割后的长度为:2,分割后的结果为: "a" "b"
"-a-b" 分割后的长度为:3,分割后的结果为: "" "a" "b"
"-a-b-" 分割后的长度为:3,分割后的结果为: "" "a" "b"
"a" 分割后的长度为:1,分割后的结果为: "a"
"-" 分割后的长度为:0,分割后的结果为:
"--" 分割后的长度为:0,分割后的结果为:
"" 分割后的长度为:1,分割后的结果为: ""
由此可以得出来:
当字符串只包含分隔符时,返回数组没有元素;
当字符串不包含分隔符时,返回数组只包含一个元素(该字符串本身);
字符串最尾部出现的分隔符可以看成不存在,不影响字符串的分隔;
字符串最前端出现的分隔符将分隔出一个空字符串以及剩下的部分的正常分隔;

  

Scala基础之注解(annotation
在学习Scala的过程中,总会碰到一些注解:
// Predef.scala
@inline def implicitly[T](implicit e: T) = e @deprecated("Use `sys.error(message)` instead", "2.9.0")
def error(message: String): Nothing = sys.error(message) // Spark RDD.scala
abstract class RDD[T: ClassTag](
@transient private var sc: SparkContext,
....) 一般来说,注解可以作用于vals, vars, defs, classes, objects, traits 和 types甚至是表达式的后面。
import scala.reflect.runtime.{ universe => ju } def meth[A: ju.TypeTag](xs: List[A]) = xs match {
case strList: List[String @ unchecked]
if ju.typeTag[A].tpe =:= ju.typeOf[String] => "list of Strings"
case barList: List[Bar @ unchecked]
if ju.typeTag[A].tpe =:= ju.typeOf[Bar] => "list of Bar"
} 我们知道List[T]在运行时会被类型擦除,相当于变成List。@unchecked 告诉compiler不要去检查这个,否则就会报下面的warning。
non-variable type argument String in type pattern List[String] is unchecked
since it is eliminated by erasure 另外, 注解实际上也是普通的类只不过编译器对其进行特殊的支持,所以我们才能那样书写。比如说,我们常见的序列号的注解。
class SerialVersionUID(uid: Long) extends scala.annotation.StaticAnnotation @SerialVersionUID(13567156)
class B {} @deprecated("use newShinyMethod() instead", "since 2.3")
def bigMistake() = //...
bigMistake scalac -deprecation Deprecation2.scala warning: method bigMistake in class B is deprecated: use newShinyMethod() instead
println(bigMistake)
^
one warning found @volatile
实际上这个注解或是关键字,大多用于被并发访问的共享变量。在JVM内存模型中happens-before规则有一条就是volatile变量法则(有兴趣可以阅读Java并发编程实践 第16章Java内存模型),对于volatile变量,同一变量的写操作总是先于读操作。
class Person(@volatile var name: String) {
def set(changedName: String) {
name = changedName
}
} @tailrec
这个注解是与尾递归优化有关的。
// 阶乘
def factorial(n: Int) = {
@tailrec def go(n: Int, acc: Int): Int = {
if (n <=0) acc
else go(n-1, acc * n)
// 尾递归,顾名思义方法的调用也必须出现在返回值的位置
}
go(n, 1)
} @Unchecked
一般是在模式匹配的时候用到的,告诉编译器有些地方不用"检查"了。如前所述,List[String @ unchecked]。
@transient
这个注解一般用于序列化的时候,标识某个字段不用被序列化。
import java.io.{ FileOutputStream, FileInputStream }
import java.io.{ ObjectOutputStream, ObjectInputStream } class Hippie(val name: String, @transient val age: Int) extends Serializable object Serialization { val fos = new FileOutputStream("hippie.txt")
val oos = new ObjectOutputStream(fos) val p1 = new Hippie("zml", 34)
oos.writeObject(p1)
oos.close()
} object Deserialization extends App { val fis = new FileInputStream("hippie.txt")
val ois = new ObjectInputStream(fis) val hippy = ois.readObject.asInstanceOf[Hippie]
println(hippy.name)
println(hippy.age)
ois.close()
} 运行之后的结果
zml
0 由于age被标记为@transient,在反序列化的时候,就获取不到原始值了所以被赋值为默认值。
@inline
这个注解,在Scala.Predef中见到过一次。官方文档中的解释跟没说一样, 倒是StackOverflow上一个的答案,个人觉得比较能说明作用。
Instead of a function call resulting in parameters being placed on the stack and an invoke operation occurring, the definition of the function is copied at compile time to where the invocation was made, saving the invocation overhead at runtime.
大致的意思就是@inline能够避免方法的参数被放到栈上,以及"显示的调用"。因为编译器在编译的时候会将整个方法复制到它被调用的地方。
http://stackoverflow.com/questions/4593710/when-should-i-and-should-i-not-use-scalas-inline-annotation

  

scala 基础知识总结的更多相关文章

  1. Scala基础知识[一]

    摘要:在Scala 是 Scalable Language 的简写,是一门多范式(multi-paradigm)的编程语言.设计初衷是要集成面向对象编程和函数式编程的各种特性.Scala 运行在Jav ...

  2. SCALA基础知识学习

    注:本文只说和Java不同的地方. 总结自: Scala详细教程 Scala教程 scala基础语法 Scala 与 Java 的最大区别是:Scala 语句末尾的分号 ";" 是 ...

  3. Scala基础知识笔记1

    上一篇文章介绍了如何下载scala, 因为在官网上点击下载按钮无法下载, 下面介绍scala的基础语法: 1 scala和java的关系 Scala是基于jvm的一门编程语言,Scala的代码最终会经 ...

  4. (数据科学学习手札45)Scala基础知识

    一.简介 由于Spark主要是由Scala编写的,虽然Python和R也各自有对Spark的支撑包,但支持程度远不及Scala,所以要想更好的学习Spark,就必须熟练掌握Scala编程语言,Scal ...

  5. [Scala] Scala基础知识

    Object An object is a type of class that can have no more than one instance, known in object-oriente ...

  6. 为Play初学者准备的Scala基础知识

    1 前言 本文的主要目的是为了让Play Framework的初学者快速了解Scala语言,算是一篇Play Framework的入门前传吧.使用PlayFramework可以极大的提高开发效率,但是 ...

  7. 【转】Scala基础知识

    原文地址.续 课程内容: 关于这节课 表达式 值 函数 类 继承 特质 类型 apply方法 单例对象 函数即对象 包 模式匹配 样本类 try-catch-finally 关于这节课 最初的几个星期 ...

  8. Scala基础知识笔记2

    1 类 1.1 定义一个简单的类 1.2 field的getter 和 setter方法 感觉成员变量定义成  var 属性名=属性值即可,  不需要定义成 val 或者 private就行, // ...

  9. Scala基础知识(二)

    1.条件表达式 object ConditionDemo { def main(args: Array[String]) { val x = //判断x的值,将结果赋给y val y = ) //打印 ...

随机推荐

  1. android studio 下载 sdk 失败

    android studio 打开项目出现以下错误时,点击去安装,会提示"All packages are not available for download" 错误. 解决办法 ...

  2. 软件测试----H模型

    H模型将测试活动完全独立出来,形成一个完整的流程,同时将测试准备和测试执行清晰表现出来. 测试流程: --测试准备:所有测试活动的准备判断是否到测试就绪点. --测试就绪点:测试准入准则,即是否可以开 ...

  3. WebGL模型拾取——射线法二

    这篇文章是对射线法raycaster的补充,上一篇文章主要讲的是raycaster射线法拾取模型的原理,而这篇文章着重讲使用射线法要注意的地方.首先我们来看下图. 我来解释一下上图中的originTr ...

  4. 利用KMP算法解决串的模式匹配问题(c++) -- 数据结构

    题目: 7-1 串的模式匹配 (30 分) 给定一个主串S(长度<=10^6)和一个模式T(长度<=10^5),要求在主串S中找出与模式T相匹配的子串,返回相匹配的子串中的第一个字符在主串 ...

  5. PHPMyWind5.4存储XSS后续getshell提权

    0x0 前言 通过留言处的xss,我们可以得到管理员的cookie,进而登陆后台: https://www.cnblogs.com/Rain99-/p/10701769.html 现在要从后台入手,进 ...

  6. PAT甲题题解-1077. Kuchiguse (20)-找相同后缀

    #include <iostream> #include <cstdio> #include <algorithm> #include <string.h&g ...

  7. 20135202闫佳歆--week5 课本18章学习笔记

    第十八章 调试 内核级开发的调试工作远比用户级开发艰难的多. 一.准备开始 准备工作需要的是: 一个bug 一个藏匿bug的内核版本 相关内核代码的知识和运气 在这一章里,调试的主要思想是让bug重现 ...

  8. Daily Scrum - 11/25

    今天是Sprint 2的最后一天,我们在下午的课上对之前两个Sprint作了比较详尽的Review,并在课后Daily Scrum上讨论制订了Sprint 3的任务安排.具体Task会在明天更新在TF ...

  9. FZU-SE-K 第一次累计得分排行榜

    FZU-SE-K 第一次累计得分排行榜 包含第一.二.三次作业 排行 恭喜 248 文航 同学获得本期小黄衫 原图戳 这里 明细 1 - 第一次作业映射分数 2 - 第二次作业映射分数 3 - 第三次 ...

  10. Beta 冲刺 三

    团队成员 051601135 岳冠宇 031602629 刘意晗 031602248 郑智文 031602330 苏芳锃 031602234 王淇 照片 项目进展 岳冠宇 ## 项目进展 昨天的困难 ...