一、类的检查和转换 -------------------------------------------------------- 1.类的检查 isInstanceOf -- 包括子类 if( p.isInstanceOf[Employee]) { println("是"); } 2.精确类的检查 classOf -- 不包括子类 if(p.getClass == classOf[Employee]) { } 3.类的转换 asInstanceOf[强转] if( p.isInstanceOf[Employee]) { //s 的 类型是Employee val s = p.asInstanceOf[Employee]; } 二、类的继承 ---------------------------------------------------------- 1.带主构造继承 scala> class Animal(val name:String){} scala> class Dog(name:String,val age:Int) extends Animal(name){} 2.抽象类的继承 a.抽象类 scala> abstract class Animal(val name:String){ //抽象字段,没有初始化。 val id:Int ; //抽象方法,没有方法体,不需要抽象关键字修饰。 def run() ; } b.继承 scala> class Dog(name:String,val age:Int) extends Animal(name){ override def run() { ... } } 3.scala继承树 AnyVal[值类型] <-- Int| Byte | Unit Any AnyRef[引用类型] <-- class | Nothing 三、文件 ------------------------------------------------------------------ 1.读取行 package test.demo1 import scala.io.Source object FileDemo { def main(args: Array[String]): Unit = { //第一个参数可以是字符串或者java.io.File val s = Source.fromFile("d:/calllog.log","UTF-8") ; val lines = s.getLines(); for(line <- lines){ println(line) } } } 2.读取字符 package test.demo1 import scala.io.Source object FileDemo { def main(args: Array[String]): Unit = { val s = Source.fromFile("d:/calllog.log") ; //打印每个字符 for(c <- s) { print(c); } } } 3.文件转换成字符串 var s = Source.fromFile("d:/calllog.log").mkString; println(s); 4.使用正则表达式读取文件 -- 按照空白字符分割文件 package test.demo1 import scala.io.Source object FileDemo { def main(args: Array[String]): Unit = { var s = Source.fromFile("d:/calllog1.log").mkString //匹配所有空白字符 var ss = s.split("\\s+"); for(sss <- ss) { println(sss); } } } 5.从URL或者其他源中读取文件 val source1 = Source.fromURL("http://xxxxxx"); val source1 = Source.fromString("hello world"); 6.通过正则实现爬虫 -- 正则href解析 val str = Source.fromFile("d:/scala/1.html").mkString val p = Pattern.compile("<a\\s*href=\"([\u0000-\uffff&&[^\u005c\u0022]]*)\""); val m = p.matcher(str); while (m.find()) { val s = m.group(1); System.out.println(s); } 7.读取二进制文件 val file = new File(filename); val in = new FileInputStream(file) val bytes = new Array[Byte](file.length.toInt) in.read(bytes) in.close() 8.写入文本文件 val out = new PrintWriter("a.txt"); for(i <- 1 to 100) { out.println(i)}; } out.close(); 9.递归遍历某目录下的所有子目录 object FileDemo { def subdirs(dir:File):Iterator[File] = { val child = dir.listFiles.filter(_.isDirectory); child.toIterator ++ child.toIterator.flatMap(subdirs _) } def main(args: Array[String]): Unit = { for(d <- subdirs(new File("D:\\Downloads"))) { println(d) } } } 四、特质trait[接口] -------------------------------------------------------- 1.普通特质:特质可以同时拥有抽象和具体方法 trait Logger{ def log(msg:String); //抽象方法,没有方法体 } //用extends而不是implements class ConsoleLogger extends Logger { //不需要写override def log(msg : String) { println(msg); } } 2.自带实现方法的特质 trait ConsoleLogger{ def log(msg:String){ println(msg); }; } class A extends B with ConsoleLogger{ def func(d : Double){ if(d > 10) log("大于10"); } } 3.trait的多继承 //如果只有一个trait使用extends进行扩展,如果多个,使用with对剩余的trait进行扩展。 trait logger1{ def log1() = println("hello log1"); } trait logger2{ def log2() = println("hello log2"); } trait logger3{ def log3() = println("hello log3"); } class Dog extends logger1 with logger2 with logger3{ } 4.trait之间的继承 trait logger1{ def log1() = println("hello log1"); } trait logger2 { def log2() = println("hello log2"); } trait logger3 extends logger2 with logger1{ } 5.自身类型 [this:Dog =>] -- 限定trait的子类类型,就是只有属于限定类型的子类,才可以继承这个trait class Dog { } trait logger{ this:Dog => def run() = println("run....") } //可以继承logger,因为Jing8 extends Dog class Jing8 extends Dog with logger{ } //不可以继承logger,因为猫和狗没有关系 class Cat extends logger{ } 五、操作符 -------------------------------------------------------- 1.中置操作符:操作符在中间 a 中置标识符 b // 1->2 1+2 2.一元操作符,只操作一个参数 a 一元标识符 //1.toString +1 -1 ~1[按位取反] !true[布尔取反] 3.赋值操作符 a 操作符= b //a += b 4.结合性[左结合:从左向右计算 右结合:从右向左计算] a.scala中所有的操作符都是左结合的,除了 1)以冒号(:)结尾的操作符 2)赋值操作符 b.构造列表操作符[::],是右结合的 1)创建一个空的集合 scala> val a = Nil a: scala.collection.immutable.Nil.type = List() 2)给空集合增加单个元素 scala> 1::Nil res1: List[Int] = List(1) 3)给空集合增加多个元素 scala> 1::2::Nil res1: List[Int] = List(1,2) 相当于 scala> val list = 2::Nil list: List[Int] = List(2) scala> 1::list res4: List[Int] = List(1, 2) 因为如果是从左计算的,结果应该如下 scala> val list = 1::Nil list: List[Int] = List(1) scala> 2::list res5: List[Int] = List(2, 1) 六、apply() / update() /unapply() -------------------------------------------------------- 1.apply/update val scores = new scala.collection.mutable.HashMap[String,Int] scores("bob") = 100 ==> scores.update("bob",100) val bobs = scores("bob") ==> scores.apply("bob") scala> Array.apply(100) res34: Array[Int] = Array(100) scala> Array(100) res35: Array[Int] = Array(100) scala> f.update(0,100) scala> f(0) = 200 2.unapply //定义类 class Fraction(val n:Int,val d:Int){ } object Fraction{ //通过 def apply(n : Int,d:Int)= new Fraction(n,d) //逆向过程 def unapply(f:Fraction) = Some(f.n,f.d) } scala> val f = Fraction(1,2) f: Fraction = Fraction@5f33123 scala> f.n res41: Int = 1 scala> f.d res42: Int = 2 scala> val Fraction(a,b) = f a: Int = 1 b: Int = 2 七、高阶函数 ----------------------------------------------- 1.函数类型的变量,将函数赋值给一个变量 scala> def add(a:Int,b:Int) = a + b add: (a: Int, b: Int)Int scala> add(1,2) res43: Int = 3 scala> val f = add _ f: (Int, Int) => Int = <function2> scala> f(1,2) res44: Int = 3 2.函数作为参数 scala> def add(a:Int) = a + 1 add: (a: Int)Int scala> val f = add _ f: Int => Int = <function1> //Array().map() ==> map方法接受一个函数作为参数,对集合中的所有值进行函数运算,并返回新的集合 scala> Array(1,2,3).map(add); res2: Array[Int] = Array(2, 3, 4) scala> Array(1,2,3).map(f) res3: Array[Int] = Array(2, 3, 4) 3.匿名函数[(n:Double) => n *3] scala> val f = (n:Double) => n *3 //等价于 def f(n:Double) = n *3 f: Double => Double = <function1> scala> f(3) res5: Double = 9.0 scala> Array(1,2,3).map((n:Int) => n * 3) res7: Array[Int] = Array(3, 6, 9) 4.遍历数组输出元素值,每个元素平方返回 def fun(n:Array[Int]) = { for(e <- n) println(e) val f = for(e <- n) yield e * e f } scala> val f = fun(Array(1,2,3)) 1 2 3 f: Array[Int] = Array(1, 4, 9) 5.函数作为函数的参数,并且在函数体中调用参数函数 val f1 = (a:Int,b:Int) => a + b val f2 = (a:Int,b:Int) => a - b def call(a:Int,b:Int,f1:(Int,Int)=>Int,f2:(Int,Int)=>Int)={ if(a > 0) f1(a,b); else f2(a,b); } scala> call(1,2,f1,f2) res23: Int = 3 scala> call(-1,2,f1,f2) res24: Int = -3 6.参数和返回值都是函数 val f1 = (a:Int,b:Int) => a + b val f2 = (a:Int,b:Int) => a - b def call(a:Int,b:Int,f1:(Int,Int)=>Int,f2:(Int,Int)=>Int):(Int)=>Int={ var res = 0; if(a > 0){ res = f1(a,b); } else { res = f2(a,b); } var f = (n:Int) => n * res return f } scala> val f = call(1,2,f1,f2) f: Int => Int = <function1> scala> f(2) res26: Int = 6 7.高阶函数的简写(1) def valueAt(f:Double => Double) = { f(0.25); } scala> import scala.math._ import scala.math._ scala> valueAt(ceil _) res28: Double = 1.0 scala> valueAt(sqrt _) res29: Double = 0.5 8.高阶函数的简写(2) def mulby(factor : Double) = { (x:Double) => x * factor; } scala> val f = mulby(2.0) f: Double => Double = <function1> scala> f(2) res33: Double = 4.0 9.函数推断 def valueAt(f:(Double)=>Double) = f(0.25) scala> valueAt(x => x * 3) //等价于 valueAt((x:Double) => x * 3),scala自动推断参数类型 scala> valueAt(3 * _) //等价于 valueAt((x:Double) => x * 3),参数在右侧只出现一次,使用下划线代替 res0: Double = 0.75 scala> val arr = Array(1,2,3,4) arr: Array[Int] = Array(1, 2, 3, 4) scala> arr.map(_ * 3) //参数在右侧只出现一次,使用下划线代替 scala> arr.map((e:Int) => e * 3) //等价 scala> arr.map(e => e * 3) //等价 res4: Array[Int] = Array(3, 6, 9, 12) //先打印数组,后将数组方法三倍 scala> arr.map( e=> {println(e); e * 3} ) 1 2 3 4 res7: Array[Int] = Array(3, 6, 9, 12) 10.数组过滤arr.filter //取数组中所有的偶数值 scala> val arr = Array(1,2,3,4) arr: Array[Int] = Array(1, 2, 3, 4) scala> arr.filter(e=> e % 2 == 0) res8: Array[Int] = Array(2, 4) //链式编程 -- 先扩大三倍然后过滤取偶数 scala> arr.map(_ * 3).filter( _ % 2 == 0 ) res9: Array[Int] = Array(6, 12) 11.一些有用的高阶函数 a. "*" ,将一个字符重复n次 scala> "a" * 3 res10: String = aaa scala> "ab" * 3 res11: String = ababab b.foreach(),遍历集合,并对每个元素应用函数 scala> (1 to 9).map("*" * _ ).foreach(println(_)) * ** *** **** ***** ****** ******* ******** ********* scala> (1 to 9).map(e => "*" * e ).foreach(e => println(e)) * ** *** **** ***** ****** ******* ******** ********* c.reduceLeft 方法接受一个二元的函数 -- 即一个带有两个参数的函数,并将函数应用到序列中的所有元素中 scala> (1 to 9).reduceLeft(_ * _) res21: Int = 362880 //相当于 9! scala> (1 to 9).reduceLeft((x,y)=> x-y) res24: Int = -43 //相当于 1-2-3-4-5-6-7-8-9 d.reduceRight/reduceLeft //从右侧开始化简 -- (1 - (2 - (3 - 4))) scala> (1 to 4).reduceRight(_ - _) res29: Int = -2 //从左侧开始化简 -- (((1 - 2) - 3) - 4) scala> (1 to 4).reduceRight(_ - _) res29: Int = -8 d.sortWith 方法接受一个二元的函数,然后进行排序,输出一个数组 scala> val a = "Hello World Tom HAHAHAHA" a: String = Hello World Tom HAHAHAHA scala> a.split(" ") res32: Array[String] = Array(Hello, World, Tom, HAHAHAHA) scala> a.split(" ").sortWith((x,y)=> x.length < y.length) scala> a.split(" ").sortWith(_.length < _.length) res33: Array[String] = Array(Tom, Hello, World, HAHAHAHA) e.闭包:函数中传递的参数,然后将函数赋值给一个变量,那么这个变量就永久的持有这个参数了 def mulBy(fac : Double) = { (x :Double) => fac * x; } val f1 = mulBy(3); //f1 就永久的持有3这个参数因子,即使MulBy已经结束 val f2 = mulBy(0.5); //f2 就永久的持有0.5这个参数因子,即使MulBy已经结束 scala> println(f1(3) + ":" + f2(3)) 9.0:1.5 八、柯里化 ---------------------------------------------------------------- 1.方法链式化 将多参数的一个函数,变成只有一个参数的多函数,达到每个函数仅有一个参数,每个函数仅完成一个任务,达到简化的目的 2.两个参数的函数的另外一种写法[为了将参数单个的隔离出来] :一个新的函数,以原来的一个参数为参数,返回值是一个函数,并且返回的函数是,以原来的函数的另外一个参数为参数,的函数 scala> def mul(x:Int,y:Int) = { x * y } mul: (x: Int, y: Int)Int scala> def mulOne(x :Int) = { ( y:Int ) => x * y } scala> def mulOne(x :Int)(y :Int) = x * y mulOne: (x: Int)Int => Int scala> mulOne(5)(6) res37: Int = 30 scala> mul(5,6) res38: Int = 30 九、控制抽象 ----------------------------------------------------------- 1.定义过程,启动分线程执行block代码,将线程执行的代码抽离成参数 def newThread( block : () => Unit ){ new Thread(){ override def run() { block(); } }.start(); } newThread( () =>{ (1 to 10).foreach( (e) => { val tname = Thread.currentThread.getName(); println(tname + " " + e) } ) } ); scala> Thread-2 1 Thread-2 2 Thread-2 3 Thread-2 4 Thread-2 5 Thread-2 6 Thread-2 7 Thread-2 8 Thread-2 9 Thread-2 10 2.换名调用表示法() => 在参数声明和调用的时候都省略(),但保留=> def newThread( block : => Unit ){ new Thread(){ override def run() { block; } }.start(); } newThread( (1 to 10).foreach( e => { val tname = Thread.currentThread.getName(); println(tname + " " + e) } ) ); 十、集合 ----------------------------------------------------------- 1.不可变:List //Nil空集合 scala> val l = List(1,2,3,4,5) l: List[Int] = List(1, 2, 3, 4, 5) scala> l.head res50: Int = 1 scala> l.tail res51: List[Int] = List(2, 3, 4, 5) scala> 9::l res52: List[Int] = List(9, 1, 2, 3, 4, 5) 2.递归计算集合中所有元素的和 def sum(lst:List[Int]) : Int = { if(lst == Nil) 0 else lst.head + sum(lst.tail) } 3.模式匹配,实现sum求和 def sum(lst : List[Int]) : Int = { lst match{ case Nil => 0 case h :: t => h + sum(t) //:: 折构 ,将lst.head表示成h ,将 lst.tail表示成t } } 4.集Set(存储不重复元素) a.不重复 scala> val set = scala.collection.mutable.Set(1,2,3) set: scala.collection.mutable.Set[Int] = Set(1, 2, 3) scala> set.add(2) res56: Boolean = false scala> set res57: scala.collection.mutable.Set[Int] = Set(1, 2, 3) scala> set.add(4) res58: Boolean = true scala> set res59: scala.collection.mutable.Set[Int] = Set(1, 2, 3, 4) 5.集合的添加和删除元素操作符 a. [:+] / [+:] 向集合中添加元素,返回新的集合,原集合不变[List可以,Set不行] scala> val list = List(1,2,3) list: List[Int] = List(1, 2, 3) scala> list:+4 res67: List[Int] = List(1, 2, 3, 4) scala> 4 +: list res68: List[Int] = List(4, 1, 2, 3) b. [+] / [-] 集合中添加/移除集合,返回新的集合,无序 适用于Set和Map,不适用于List scala> set res75: scala.collection.mutable.Set[Int] = Set(1, 2, 3, 4) scala> set + (9,10) res79: scala.collection.mutable.Set[Int] = Set(9, 1, 2, 3, 10, 4) scala> set -(1,2,5) res83: scala.collection.mutable.Set[Int] = Set(3, 4) c. [++] / [++:] 集合中添加相同类型的集合,返回新的包含两个集合元素的集合,适用List和Set scala> set res89: scala.collection.mutable.Set[Int] = Set(1, 2, 3, 4) scala> val set1 = set + (5,6) - (1,2) set1: scala.collection.mutable.Set[Int] = Set(5, 6, 3, 4) scala> set ++ set1 res87: scala.collection.mutable.Set[Int] = Set(1, 5, 2, 6, 3, 4) scala> set ++: set1 res88: scala.collection.mutable.Set[Int] = Set(1, 5, 2, 6, 3, 4) scala> list ++ list1 res91: List[Int] = List(1, 2, 3, 4, 5, 6) scala> list1 ++ list res92: List[Int] = List(4, 5, 6, 1, 2, 3) scala> list1 ++: list res93: List[Int] = List(4, 5, 6, 1, 2, 3) d.[--] 操作两个集合,移除左侧集合中所有包含于右侧集合中的元素,返回新的集合。适用于Set,不适用List scala> set res94: scala.collection.mutable.Set[Int] = Set(1, 2, 3, 4) scala> set1 res95: scala.collection.mutable.Set[Int] = Set(5, 6, 3, 4) scala> set -- set1 res96: scala.collection.mutable.Set[Int] = Set(1, 2) e.[::] / [:::] 向集合中添加元素或者集合。返回新的集合。适用于List,不适用于Set scala> list res98: List[Int] = List(1, 2, 3) scala> 4 :: list res101: List[Int] = List(4, 1, 2, 3) scala> list1 res102: List[Int] = List(4, 5, 6) scala> list res103: List[Int] = List(1, 2, 3) scala> list1 ::: list res104: List[Int] = List(4, 5, 6, 1, 2, 3) scala> list ::: list1 res105: List[Int] = List(1, 2, 3, 4, 5, 6) f.[|] / [&] / [&~] 去两个集合的并集,交集和差集,返回新的集合。适用于set不适用List scala> set res106: scala.collection.mutable.Set[Int] = Set(1, 2, 3, 4) scala> set1 res107: scala.collection.mutable.Set[Int] = Set(5, 6, 3, 4) scala> set | set1 res108: scala.collection.mutable.Set[Int] = Set(1, 5, 2, 6, 3, 4) scala> set1 | set res109: scala.collection.mutable.Set[Int] = Set(1, 5, 2, 6, 3, 4) scala> set & set1 res110: scala.collection.mutable.Set[Int] = Set(3, 4) scala> set &~ set1 res111: scala.collection.mutable.Set[Int] = Set(1, 2) scala> set1 &~ set res112: scala.collection.mutable.Set[Int] = Set(5, 6) g. +=, ++=, -=, --= 带赋值=,改变原有集合,不产生新集合,适用于Set,不适用于List scala> set res113: scala.collection.mutable.Set[Int] = Set(1, 2, 3, 4) scala> set += 5 res114: set.type = Set(1, 5, 2, 3, 4) scala> set -= 5 res115: set.type = Set(1, 2, 3, 4) scala> set += (56,67) res123: set.type = Set(1, 67, 2, 56, 3, 4) scala> set -= (67,56) res127: set.type = Set(1, 2, 3, 4) scala> set res128: scala.collection.mutable.Set[Int] = Set(1, 2, 3, 4) scala> set1 res129: scala.collection.mutable.Set[Int] = Set(5, 6, 3, 4) scala> set ++= set1 res130: set.type = Set(1, 5, 2, 6, 3, 4) scala> set --= set1 res131: set.type = Set(1, 2) 6.常用方法 scala> set res143: scala.collection.mutable.Set[Int] = Set(1, 5, 2, 3, 4) scala> list res147: List[Int] = List(1, 2, 3) //isEmpty scala> set.isEmpty res134: Boolean = false //tail scala> set.tail res140: scala.collection.mutable.Set[Int] = Set(5, 2, 3, 4) //head scala> set.head res141: Int = 1 //init scala> set.init res142: scala.collection.mutable.Set[Int] = Set(1, 5, 2, 3) //length scala> list.length res146: Int = 3 //take(n) scala> list.take(2) res152: List[Int] = List(1, 2) scala> set.take(2) res153: scala.collection.mutable.Set[Int] = Set(1, 5) //drop(n) scala> set.drop(2) res154: scala.collection.mutable.Set[Int] = Set(2, 3, 4) //splitAt(n) scala> list.splitAt(2) res157: (List[Int], List[Int]) = (List(1, 2),List(3)) //zip scala> import scala.collection.mutable.ArrayBuffer import scala.collection.mutable.ArrayBuffer scala> val b1 = ArrayBuffer(1,2,3) b1: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3) scala> val b2 = ArrayBuffer(3,4,5,6) b2: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(3, 4, 5, 6) scala> b1.zip(b2) res158: scala.collection.mutable.ArrayBuffer[(Int, Int)] = ArrayBuffer((1,3), (2,4), (3,5)) scala> b2.zip(b1) res159: scala.collection.mutable.ArrayBuffer[(Int, Int)] = ArrayBuffer((3,1), (4,2), (5,3)) //zipAll scala> b1.zipAll(b2,-1,-2) res160: scala.collection.mutable.ArrayBuffer[(Int, Int)] = ArrayBuffer((1,3), (2,4), (3,5), (-1,6)) scala> b2.zipAll(b1,-1,-2) res161: scala.collection.mutable.ArrayBuffer[(Int, Int)] = ArrayBuffer((3,1), (4,2), (5,3), (6,-2)) //zipWithIndex scala> b1.zipWithIndex res163: scala.collection.mutable.ArrayBuffer[(Int, Int)] = ArrayBuffer((1,0), (2,1), (3,2)) //folderLeft scala> List(1,7,2,9).foldLeft(0)(_ - _) //相当于 ((((0 - 1) - 7) - 2) - 9) = -19 res167: Int = -19 //folderRight scala> List(1,7,2,9).foldRight(0)(_ - _) //相当于 (1 - (7 - (2 - (9 - 0)))) = -13 res168: Int = -13
大数据之scala(三) --- 类的检查、转换、继承,文件,特质trait,操作符,apply,update,unapply,高阶函数,柯里化,控制抽象,集合
最新推荐文章于 2021-12-10 19:57:26 发布