从零学scala(五)文件和正则表达式、特质

一:文件和正则表达式

1.读取行
    import scala.io.Source
    val lines = Source.fromFile("D://report_data2.txt","UTF-8").getLines()   
    for( i <- lines) println(i)//遍历每一行的数据

    val array = Source.fromFile("D://report_data2.txt","UTF-8").toArray                    
    //将读取到的数据作为一个数组
    val mkString = Source.fromFile("D://report_data2.txt","UTF-8").mkString("|")     
    //将读取到的数据作为一个字符串
2.读取字符
    import scala.io.Source
    val lines = Source.fromFile("D://report_data2.txt","UTF-8").buffered 
    //每次只读取一个字符,个人感觉有点浪费资源了,可以一次读取更多的
    for( i <- lines) println(i)
3.读取词法单元和数字
    import scala.io.Source
    val lines = Source.fromFile("D://report_data2.txt","UTF-8").mkString.split("\\|")     
    //直接按照|切割字符串
    for( i <- lines) println(i)

    import scala.io.Source
    val lines = Source.fromFile("D://report_data2.txt","UTF-8").mkString.split("\\|")
    lines.map { x => x.toInt }.map { x => println(x)}                                                     //将数据转换为Int类型
4.从URL或其他源读取
    import scala.io.Source
    val urlLines = Source.fromURL("https://www.baidu.com/index.php","UTF-8").getLines()     
    //从URL读取
    for(i <- urlLines) println(i)

    val fromString = Source.fromString("https://www.baidu.com/index.php"
    //从字符串读取
    val fromStdin = Source.stdin
5.读取二进制文件
    import scala.io.Source
    import java.io.File
    import java.io.FileInputStream
    val file = new File("D://report_data2.txt")                       
    //不只是可以读取txt文件,还可以读取excel等
    val in = new FileInputStream(file)
    val bytes = new Array[Byte](file.length().toInt) 
    while(in.read(bytes) != -1) println(new String(bytes))     //将读取到的数据
6.生成字符串打印出来
    in.close() ;
7.写入文本文件
    import java.io.PrintWriter
    val file = new PrintWriter("D://report_data2.txt")   //其实还是java 的用法
    file.println("aa")
    file.println("bb")
    file.println("cc")
    file.println("dd")
    file.close()
8.访问目录

scala遍历目录使用的还是java的file功能,只不过使用scala语法更简单明了了

    import java.io.File

    object FastLearnScala{
            def readDir(file:File):Unit = { //打印出来目录下面所有的文件
                    for(i <- file.listFiles()){
                            if(i.isFile()) println(i.getName) else readDir(i)
                    }
            }
            def main(args: Array[String]): Unit = {
                    val file = new File("D://TGP")
                    readDir(file)
            }
    }
9.序列化
    class Persion extends Serializable{
            val name = Array("name1","name2","name3")   //Array对象已经序列化过了,所以可以直接使用
            val age = Array("age1","age2","age3")
    }
    object FastLearnScala{

            def main(args: Array[String]): Unit = {
                    //java语法占大部分,如果java比较熟悉看起来应该没有什么困难
                    val persion = new Persion
                    import java.io.File
                    import java.io.{ObjectOutputStream,ObjectInputStream}
                    import java.io.{FileOutputStream,FileInputStream}
                    val oos = new ObjectOutputStream(new FileOutputStream("D://report_data2.txt"))
                    oos.writeObject(persion);oos.flush();oos.close();
                    val ois = new ObjectInputStream(new FileInputStream("D://report_data2.txt"))
                    val readObject = ois.readObject().asInstanceOf[Persion]
                    println(readObject.age.mkString("|") + "&" + readObject.name.mkString("|"))
            }
    }
10.进程控制
    import sys.process._
    "ls -a" !//打印到控制台
    "ls -a" !!//将结果以字符串的形式返回
    "ls -a" #| "grep aa"//管道命令的使用
    import java.io.File
    "ls -a" #> new File("1.txt") ! //输出的重定向,覆盖式操作
11.正则表达式
    val numPatter = "[0-9]*".r //基本的表达式
    val wsnumPatter = """\s[0-9]+\s""".r //如果表达式中含有\的时候建议使用"""字符串"""
    for(string<- wsnumPatter.findAllIn("aaaa 1111 bbbb 2222 cccc 3333"))
    println(string)
    println("1235576879".matches(numPatter.toString())) //其实这种才是最常用的
12.正则表达式组
    val wsnumPatter = "([0-9]+) ([a-z]+)".r //基本的表达式
    for(wsnumPatter(num,str)<- wsnumPatter.findAllIn("1111 aaaa, 2222 bbbb, 3333 cccc"))
            println(num+"|"+str)

二:特质

1.为什么没有多重继承

简单说就是一个class同时继承了多了class,当你继承的class中有多个相同名称的函数或者变量的时候,你不知道该使用哪一个。

java的解决方法是:一个类只能extends一个类,但是可以实现多个接口,接口中不不能包含抽象字段的,但是可以包含抽象方法

scala的解决方法是:提供了特质这个性质:特质可以同时有抽象方法和具体方法(相当于abstract class),而且一个类可以实现多个特质

2.当做接口使用的特质
    trait logger{
            def log(msg:String){}
    }
    trait logger1{
            def log(msg:String){}
    }
    class Consolelogger extends logger with logger1{ //使用extends关键字,多个的时候后跟with
            override def log(msg:String){println(msg)}
    }

scala是基于JVM运行的所以,他的特性和JAVA一样。只能extends一个class,但是可以继承多个trait

3.带具体实现的特质
    trait logger{
            def log(msg:String){}
    }
    trait logger1{
            def console(msg:String){println("logger1:" + msg)}
    }
            class Consolelogger extends logger with logger1{ //使用extends关键字,多个的时候后跟with
            override def log(msg:String){println(msg)}
    }

    object FastLearnScala{

            def main(args: Array[String]): Unit = {
                    val consolelogger = new Consolelogger
                    consolelogger.console("aa")
            }
    }

  //其实和abstract class的用法是一致的

4.带有特质的对象
    trait logged{
            def log(msg:String){println("logged:"+msg)}
    }
    trait Consolelogger { //trait还是可以有实现方法的
            def log(msg:String){println("Consolelogger:"+msg)}
    }

叠加在一起的特质

    trait logged{
            def log(msg:String){println("logged:"+msg)}
    }
    trait Consolelogger { //使用extends关键字,多个的时候后跟with
            def log(msg:String){println("Consolelogger:"+msg)}
    }
    class Account extends logged with Consolelogger{
            override def log(msg:String){super.log(msg)}
    }

  //继承多了类的时候,以最右边实现为主

5.在特质中写抽象方法
    trait logged{
            def log(msg:String){println("logged:"+msg)}
    }
    class Account extends logged {
            override def log(msg:String){println("Account:"+msg)}//和平时一样的,就是加一个override 方法
    }
6.当做富接口使用的特质
    trait logged{
            def log(msg:String){}
            def info(msg:String){println("logged info:"+msg)}
            def warn(msg:String){println("logged warn:"+msg)}
            def error(msg:String){println("logged error:"+msg)}
    }
    class Account extends logged {

    }
    object FastLearnScala{

            def main(args: Array[String]): Unit = {
                    val consolelogger = new Account
                    consolelogger.error("aa")
            }
    }

  //scala中有很多这种抽象方法和具体方法一起使用的场景

7.特质中的具体字段
    trait Logged{
            val logged = "logged"
    }
    class Account extends Logged {
            val account = "Account"
    }
    object FastLearnScala{
            def main(args: Array[String]): Unit = {
                    val consolelogger = new Account
                    println(consolelogger.logged)
                    println(consolelogger.account)
            }
    }

    //子类会将父类所有的字段都继承过来,相同名称的会override方法覆盖
8.特质中的抽象字段
    trait Logged{
            val logged:String
    }
    class Account extends Logged {
            val logged = "Account"
    }

    //父类中未初始化的字段在子类中都必须复写
9.特质构造顺序
    trait Logged{
            val logged:String = "Logged"
    }
    trait Account extends Logged{
            override val logged:String = "Account"
    }
    trait FileLogger{
            val logged:String = "FileLogger"
    }
    trait ShortLogger extends Logged{
            override val logged:String = "ShortLogger"
    }
    class SavingsAccount extends Account with FileLogger with ShortLogger{
            override val logged = "Account"
    }
    object FastLearnScala{

            def main(args: Array[String]): Unit = {
                    val consolelogger = new SavingsAccount
                    println(consolelogger.logged)
            }
    }

    //初始化顺序为:Logged(Account父类)-->>Account-->>FileLogger -->>ShortLogger(Logged已经初始化了)

    //基本和JAVA是一致的  
10.初始化特质中的字段
    trait Logged{
            val number = 10
    }
    class Account extends Logged{
            override val number = 20
            val array = new Array[String](number)
    }

    //这个例子上面已经有了,就是初始化数组长度的时候,其实是希望初始化为20,但是父类优先初始化,导致初始化为10。

    //例子里面已经将这种错误处理了
11.扩展类的特质
    class Logged{
            val number = 10
    }
    trait Account extends Logged{
            override val number = 20
            val array = new Array[String](number)
    }

    //特质是可以extends类的
12.自身类型

没什么用

背后发生了什么
trait Logged{
val number = 10
}

    //其实还是被翻译成了interface class

    trait Logged{
            val number = 10
            def aa()={
                    println("abcd")
            }
    }

    //其实还是被翻译成了interface class+一个静态类,里面是aa的静态方法
posted @ 2019-11-10 14:42  Kotlin  阅读(208)  评论(0编辑  收藏  举报
Live2D