从零学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的静态方法
搬砖多年终不得要领,遂载源码看之望得真经。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?