一、类的检查和转换
--------------------------------------------------------
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,高阶函数,柯里化,控制抽象,集合
最新推荐文章于 2023-03-19 17:50:32 发布

1065

被折叠的 条评论
为什么被折叠?



