1.26
数据的读写
读取数据
在 Source 单例对象中提供了一些获取数据的方法。
按行读取
以行为单位,返回值是一个迭代器类型的对象,通过toArray、toList方法将数据放到数组或列表。
def main(args: Array[String]): Unit = {
//创建 Source 对象,关联数据源文件
val source = Source.fromFile("./data/1.txt")//在项目中创建一个 data目录和对应文件
//以行为单位读取数据
val lines:Iterator[String] = source.getLines()
//将读取到的数据封装到 List 集合
val list:List[String] = lines.toList
//打印结果
for(data <- list)
println(data)
//关闭 Source
source.close()
}
按字符读取
def main(args: Array[String]): Unit = {
//创建 Source 对象,关联数据源文件
val source = Source.fromFile("./data/1.txt")//默认使用utf-8
//以字符为单位读取数据
val buffered:BufferedIterator[Char] = source.buffered
//打印结果
while(buffered.hasNext)
print(buffered.next())//不能使用println
//关闭 Source
source.close()
}
如果文件内容较少,可以直接把它读取到一个字符串中:
def main(args: Array[String]): Unit = {
//创建 Source 对象,关联数据源文件
val source = Source.fromFile("./data/1.txt")
//将数据读取到字符串
val string = source.mkString
//打印结果
println(string)
//关闭 Source
source.close()
}
读取词法单元和数字
词法单元指 以特定符号间隔开的字符串
创建一个文本文件
10 2 5
11 2
5 1 3 2
读取所有整数,将结果加1并打印
def main(args: Array[String]): Unit = {
//创建 Source 对象,关联数据源文件
val source = Source.fromFile("./data/1.txt")
//将数据读取到字符串数组 \s 表示空白字符(空格,\t,\r,\n等)
val strArr:Array[String] = source.mkString.split("\\s+")
val intArr:Array[Int] = strArr.map(_.toInt)
//打印结果
for (elem <- intArr) {print(elem + " ")}//11 3 6 12 3 6 2 4 3
//关闭 Source
source.close()
}
从 URL 或其他源读取
从 URL 地址读取
val source = Source.fromURL("http:www.baidu.com")
从字符串读取
val source = Source.fromString("字符串读取数据")
读取二进制文件
示例:读取图片
def main(args: Array[String]): Unit = {
//创建File对象关联文件
val file = new File("./data/1.jpg")
//创建字节输入流
val fis = new FileInputStream(file)
val bytes = new Array[Byte](file.length().toInt)
//开始读取
val len = fis.read(bytes)
println(s"读取到的字节数:$len")
//关闭字节输入流
fis.close()
}
写入数据
要使用 Java 的类库
往文件中写入指定内容
def main(args: Array[String]): Unit = {
//创建字节输出流
val fos = new FileOutputStream("./data/1.txt")//目的地不存在会自动创建
//输出
fos.write("GetOffer".getBytes())
//关闭输出流
fos.close()
}
序列化和反序列化
要实现序列化必须继承 Serializable 特质(标记接口),如果是样例类可以省略继承
case class Person(name:String, age:Int) [extends Serializable]
def main(args: Array[String]): Unit = {
val p = Person("sjh", 24)
//序列化
val outputStream = new ObjectOutputStream(new FileOutputStream("./data/2.txt"))
outputStream.writeObject(p)
outputStream.close()
//反序列化
val inputStream = new ObjectInputStream(new FileInputStream("./data/2.txt"))
val person = inputStream.readObject().asInstanceOf[Person]//读取出的对象是AnyRef,要转换
println(person)
inputStream.close()
}
案例:学员成绩表
已知项目 data 文件夹下的 1.txt 记录了学生成绩如下:
张三 37 90 100
李四 90 73 81
王五 60 90 76
赵六 89 21 72
田七 100 100 100
按照学生总成绩进行排名,按照姓名-语文成绩-数学成绩-英语成绩-总成绩的格式,输出到 2.txt
case class Student(var name:String,var chinese:Int, var math:Int, var english:Int){
def getSum:Int = chinese + math +english
}
def main(args: Array[String]): Unit = {
//获取数据源文件
val source = Source.fromFile("./data/1.txt")
//封装到数组
val array:Iterator[Array[String]] = source.getLines().map(_.split(" "))
//定义可变列表存储学生信息
val stuList = ListBuffer[Student]()
//遍历数组,将数据封装成 Student 对象,添加到可变列表
for(s <- array){
stuList += Student(s(0), s(1).toInt, s(2).toInt, s(3).toInt)
}
//排序
val list = stuList.sortBy(_.getSum).reverse.toList
//通过字符输出流输出文件
val bw = new BufferedWriter(new FileWriter("./data/2.txt"))
bw.write("姓名 语文 数学 英语 总分")
bw.newLine()
for(s <- list){
bw.write(s"${s.name} ${s.chinese} ${s.math} ${s.english} ${s.getSum}")
bw.newLine()//换行
}
//关闭资源
bw.close()
source.close()
}
2.txt:
姓名 语文 数学 英语 总分
田七 100 100 100 300
李四 90 73 81 244
张三 37 90 100 227
王五 60 90 76 226
赵六 89 21 72 182
高阶函数
Scala 混合了面向对象和函数式特性,如果一个函数的参数列表可以接收函数对象,那么这个函数就被称为高阶函数。
作为值的函数
可以将函数对象传递给方法 。
需求:将一个整数列表中的每个元素转换为对应个数的*。
def main(args: Array[String]): Unit = {
val list = (1 to 5).toList
val func = (x:Int) => "*" * x
val list1 = list.map(func)
println(list1)//List(*, **, ***, ****, *****)
}
匿名函数
没有赋值给变量的函数就是匿名函数
def main(args: Array[String]): Unit = {
val list = (1 to 5).toList
val list1 = list.map((x:Int) => "*" * x)
val list2 = list.map("*" * _)
println(list1)//List(*, **, ***, ****, *****)
println(list2)//List(*, **, ***, ****, *****)
}
柯里化
柯里化指 将原先接收多个参数的方法转换为多个只有一个参数列表的过程
需求:定义方法完成两个字符串的拼接
object ClassDemo {
//普通写法
def merge1(str1:String, str2:String): String = str1 + str2
//柯里化 f1表示函数
def merge2(str1:String, str2:String)(f1:(String, String) => String): String = f1(str1, str2)
def main(args: Array[String]): Unit = {
println(merge1("abc", "def"))//abcdef
println(merge2("abc", "def")(_ + _))//abcdef
}
}
闭包
闭包指 可以访问不在当前作用域范围数据的一个函数。(柯里化就是一个闭包)
通过闭包获取两个整数的和:
def main(args: Array[String]): Unit = {
val x = 10
val sum = (y:Int) => x + y
println(sum(10))//20
}
控制抽象
假设函数 A 的参数列表需要接收一个函数 B,而函数B没有输入值也没有返回值,那么函数A称为控制抽象函数。
示例:
object ClassDemo {
val func = (f1:() => Unit) => {
println("welcome")
f1()
println("bye")
}
def main(args: Array[String]): Unit = {
func(() => println("shopping.."))
}
}
结果:
welcome
shopping..
bye
案例:计算器
定义一个方法,用来完成两个 Int 类型数字的计算
具体计算封装到函数中
使用柯里化完成操作
object ClassDemo {
//普通写法
def add(a:Int, b:Int): Int = a + b
def sub(a:Int, b:Int): Int = a - b
def mul(a:Int, b:Int): Int = a * b
def div(a:Int, b:Int): Int = a / b
//柯里化
def calculate(a:Int, b:Int)(func:(Int,Int) => Int): Int = func(a, b)
def main(args: Array[String]): Unit = {
println(calculate(1, 1)(_ + _))//2
println(calculate(1, 1)(_ - _))//0
println(calculate(1, 1)(_ * _))//1
println(calculate(1, 1)(_ / _))//1
}
}

浙公网安备 33010602011771号