4、集合(接著上次的集合繼續學習)
4.4可變集合
1、ListBuffer
val listBuffer1: ListBuffer[Int] = new ListBuffer[Int]
println(s"$listBuffer1")
listBuffer1.+=(11)
listBuffer1.+=(22)
listBuffer1.+=(33)
listBuffer1.+=(11)
listBuffer1.+=(55)
listBuffer1.+=(22)
listBuffer1.+=(33)
listBuffer1.+=(66)
listBuffer1.+=(33)
println(s"$listBuffer1")
/**
* 這裡的可變List集合,對於不可變的集合的功能,這裡都可以呼叫
*/
//刪除元素,從左向右找元素,只會刪除第一次找到的
val res1: listBuffer1.type = listBuffer1.-=(33)
println(s"$res1")
//批次新增元素
val res2: listBuffer1.type = listBuffer1.+=(12, 34, 56)
println(s"$res2")
//新增list集合
val list1: List[Int] = List(1, 2, 3)
val res3: listBuffer1.type = listBuffer1.++=(list1)
println(s"$res3")
2、HashSet
/**
* 可變的set集合,特點和不可變的set一致
*/
val hashset: mutable.HashSet[Int] = new mutable.HashSet[Int]
val hashset1: hashset.type = hashset.+=(1, 2, 3, 4, 5, 3, 7, 6, 8, 3)
println(s"$hashset1")
4.5Tuple
object Demo17tuple {
def main(args: Array[String]): Unit = {
/**
* 大小,值是固定的,根據建立的類來定,每個元素的資料型別可以是不一樣,最高可以建立儲存22個元素的元組
*/
// val t1: (String, Int) = Tuple2("zhangsan", 18)
// println(s"$t1")
val s1: student1 = new student1("lisi", 20, "nan")
val t2: (String, student1) = Tuple2("hello", s1)
println(t2._2.name)
}
}
case class student1(name:String,age:Int,gender:String)
4.6Map
object Demo18Map {
def main(args: Array[String]): Unit = {
//建立Map集合
//鍵是唯一的,鍵一樣的時候,值會被覆蓋
val map1: Map[Int, String] = Map((1001, "zhangsan"), (1002, "lisi"), (1003, "wangwu"), (1001, "abc"), 1004 -> "bcd")
println(s"$map1")
//根據獲取值,直接使用小括號,鍵不存在會報錯,但是使用get方法鍵不存在不會報錯
val res1: String = map1(1003)
val res2: Option[String] = map1.get(1005)
println(s"$res1")
println(s"$res2")
println(map1.getOrElse(1006,0))
val keys: Iterable[Int] = map1.keys // 獲取所有的鍵,組成一個迭代器
for (e <- keys) {
println(e)
}
println("=" * 50)
val values: Iterable[String] = map1.values // 獲取所有的值,組成一個迭代器
for (e <- values) {
println(e)
}
//遍歷Map集合第一種方式,先獲取所有的鍵,根據鍵獲取每個值
val res5: Iterable[Int] = map1.keys
for(e<-res5){
val value1: Any = map1.getOrElse(e, 0)
println(s"鍵:${e}, 值:${value1}")
}
//遍歷Map集合第二種方式,先獲取所有的鍵,根據鍵獲取每個值
for (kv <- map1) { // 直接遍歷map集合,得到每一個鍵值對組成的元組
println(s"鍵:${kv._1}, 值:${kv._2}")
}
//遍歷Map集合第三種方式,先獲取所有的鍵,根據鍵獲取每個值,採用foreach迴圈的方式
map1.foreach((kv:(Int,String))=>println(s"鍵:${kv._1}, 值:${kv._2}"))
}
}
5、Scala中的JDBC
* jdbc的連線步驟
* 1、註冊驅動
* 2、建立資料庫連線物件
* 3、建立資料庫操作物件
* 4、執行sql語句
* 5、如果第四步是查詢語句,那麼就需要分析查詢結果
* 6、釋放資源
object Demo19JDBC {
def main(args: Array[String]): Unit = {
//1.註冊驅動
Class.forName("com.mysql.cj.jdbc.Driver")
//2、建立資料庫連線物件
//jdbc:資料庫名://host:port/資料庫?xxx=xxx&xxx=xxx
val conn: Connection = DriverManager.getConnection("jdbc:mysql://192.168.214.100:3306/Scala_test?useUnicode=true&characterEncoding=UTF-8&useSSL=false", "root", "123456")
//建立資料庫操作物件
val preparedStatement: PreparedStatement = conn.prepareStatement("select * from students where clazz=?")
//執行sql語句,提交任務執行
preparedStatement.setString(1,"理科二班")
val resultSet: ResultSet = preparedStatement.executeQuery()
//分析
while (resultSet.next()){
val id: Int = resultSet.getInt("id")
val name: String = resultSet.getString("name")
val age: Int = resultSet.getInt("age")
val gender: String = resultSet.getString("gender")
val clazz: String = resultSet.getString("clazz")
println(s"學號:$id, 姓名:$name, 年齡:$age, 性別:$gender, 班級:$clazz")
}
//關閉連線
conn.close()
}
}
6、Scala中讀取json資料
import com.alibaba.fastjson.{JSON,JSONArray,JSONObject}
import scala.io.Source
object ScalaJson {
def main(args: Array[String]): Unit = {
//讀取json檔案資料
val lineList: List[String] = Source.fromFile("scala/data/stu.json").getLines().toList
val strJson: String = lineList.mkString("\r\n")
/**
* 使用fastjson包中的JSON類,將一個字串轉換成json格式
* 轉換成json物件之後可以透過鍵獲取值
* parseObject將整體轉換成一個json資料
*/
val parObject: JSONObject = JSON.parseObject(strJson)
//獲取對應鍵的值
val stuList: String = parObject.getString("student_list")
println(stuList)
/**
* parseArray是將"[{},{}]"變成一個元素是json物件的陣列
*/
val arr1: JSONArray = JSON.parseArray(stuList)
var i=0
//while迴圈遍歷陣列的元素,再利用鍵獲取值
while (i<arr1.size()){
val Object: JSONObject = arr1.getJSONObject(i)
val name: String = Object.getString("name")
val like: String = Object.getString("like")
println(s"${name}的愛好是${like}")
i+=1
}
}
}
7、Java轉換成Scala
Java中的集合原本是無法轉換成Scala中的集合的,沒有對應的方法
如果要實現轉換,我們需要匯入隱式轉換
匯入
import java.util
import scala.collection.JavaConverters._
注意:Scala中的導包可以放在任意位置
import java.util
import scala.collection.JavaConverters._
object Demo21Scala2Java {
def main(args: Array[String]): Unit = {
//建立一個Java的集合
val javaList: util.ArrayList[Int] = new util.ArrayList[Int]()
javaList.add(11)
javaList.add(22)
javaList.add(33)
javaList.add(44)
javaList.add(45)
javaList.add(77)
println(javaList)
val scalaList: List[Int] = javaList.asScala.toList
println(scalaList)
/**
* 對於Scala的集合可以進行轉換成Java集合
*/
val list1: util.List[Int] = scalaList.asJava
println(list1)
}
}
8、Scala中的模式匹配
模式匹配可以幫助我們在開發的時候,減少程式碼量,讓邏輯看起來更加清晰,以及可以避免一些異常
語法:
表示式 match {
case 值|[變數名:變數型別]|元組|陣列|物件 =>
匹配成功執行的語句
case xxx=>
xxx
_ xxx=>
xxx
}
模式匹配中,如果沒有對應的匹配,那麼就報錯!!!
//匹配變數值
var a: Int = 100
a match {
case 20 => println("20")
case 50 =>println("50")
case _ =>println("true")
// case 100=>println("true")
}
//匹配資料型別
var b:Any=Int
b match {
case Int=>println("true")
case Boolean=>println("false")
}
//匹配元組
val t1: (Int, String, Int) = Tuple3(10001, "zhangsan", 18)
t1 match {
case (a1:Int,a2:String,a3:Int)=>println("true")
}
//匹配陣列
val arr1: Array[Any] = Array(1001, "zhangsan", 18, "nan", "oneClazz")
arr1 match {
case Array(id:Int,name:String,gender:Int,age:String,clazz:String)=>
println(s"學號:$id, 姓名:$name, 性別:$gender, 年齡:$age, 班級:$clazz")
}
- 模式匹配的應用
/**
* 模式匹配應用1:避免異常
*/
val map1: Map[Int, String] = Map((1001, "zhangsan"), (1002, "lisi"))
//使用match的方式
val sc: Scanner = new Scanner(System.in)
println("請輸入要查詢的鍵:")
val key: Int = sc.nextInt()
map1.get(key) match {
case Some(a:Any)=>println(s"${key}鍵對應的值為$a")
case None=>println("none")
}
/**
* 模式匹配的應用2:簡化程式碼
*
*/
//不使用match的方法,正常寫法
val l1: List[String] = Source.fromFile("scala/data/students.txt").getLines().toList
// l1.map((e:String)=>e.split(","))
// .map((e:Array[String])=>{
// val id: String = e(0)
// val name: String = e(1)
// val age: String = e(2)
// val gender: String = e(3)
// val clazz: String = e(4)
// (id,name,age,gender,clazz)
// }).foreach(println)
//使用模式匹配的方式,簡化程式碼
val arrList: List[Array[String]] = l1.map((e: String) => e.split(","))
/**
* 這裡的map使用大括號 {} 而不是小括號 ()
* 是因為大括號可以定義一個程式碼塊(block),而小括號通常用於傳遞引數給函式
*/
arrList.map {
case Array(id: String, name: String, age: String, gender: String, clazz: String) =>
(id, name,age,gender,clazz)
}
9、Scala中的隱式轉換
將一個A型別將來會自動地轉換成另一個B型別,型別可以是基本資料型別,也可以是引用資料型別
- 顯示轉換:
- 直接在變數後面使用to的方式轉換,例如toInt
- 或者在函式中傳入引數不匹配時,將引數直接to的方式轉換型別
9.1 隱式轉換函式
//需求:呼叫fun1函式,就只傳字串,不會報錯
//定義隱式轉換函式
//在需要返回值型別的功能的時候,自動地根據已有隱式轉換函式將引數的型別轉成返回值的型別
implicit def implicitFun1(e:String):Int={
return Integer.parseInt(e)
}
//同時定義不止一個隱式轉換函式,則效果會不存在
// implicit def implicitFun2(e:String):Int={
// return Integer.parseInt(e)+1000
// }
def fun1(e:Int):Int = e + 1000
val res1: Int = fun1("100")
println(res1)
/**
* 對於字串方法的使用,如果字串中存在該方法會自動使用字串中的方法,
* 而不會使用隱式轉換函式的方法
*
*/
println("1000" + 500) // 1000500 // 使用字串自身的+拼接功能,做字串拼接
println("1000" - 500) // 500 // 字串中沒有-減法功能,自動使用隱式轉換中的函式,將字串轉成數字做減法
println("2000" - 500) // 1500 // 字串中沒有-減法功能,自動使用隱式轉換中的函式,將字串轉成數字做減法
/**
* 對於讀取檔案的隱式轉換函式的應用
* 直接自動識別出路徑,然後實現getlines的方法
*/
implicit def implicitFun3(path:String): BufferedSource = Source.fromFile(path)
"scala/data/students.txt".getLines().toList.foreach(println)
9.2隱式轉換類
object Demo24Implicit2 {
def main(args: Array[String]): Unit = {
/**
* 在定義隱式轉換類時,要注意在object中定義:
* `implicit' modifier cannot be used for top-level objects
* implicit class Demo12(path: String) {
* implicit使用的地方,不能超過object作用域
*/
//一般的呼叫函式的方法
// val demo: Demo1 = new Demo1("scala/data/students.txt")
// demo.show1().foreach(println)
//使用隱式轉換函式
val list1: List[String] = "scala/data/students.txt".show1()
list1.foreach(println)
"zhangsan".fun1()
}
implicit class Demo1(path:String){
//定義一個方法
def show1():List[String]={
Source.fromFile(path).getLines().toList
}
def fun1():Any={
println(s"好好學習,天天向上!$path")
}
}
}
9.3隱式轉換引數
注意:要定義隱式轉換變數,前提就是需要定義一個隱式轉換引數
object Demo25Implicit3 {
def main(args: Array[String]): Unit = {
//定義一個隱式轉換引數
def fun1(a1: Int)(implicit a2: Int): Int = a1 + a2
//定義一個隱式轉換變數
implicit var b1: Int = 100
val i: Int = fun1(100)
println(i)
}
}
10、WordCount例項
package com.scala.jichu
import scala.io.{BufferedSource, Source}
object WordCount {
def main(args: Array[String]): Unit = {
//1、讀取資料檔案,將每一行的資料封裝成集合的元素
val list1: List[String] = Source.fromFile("scala/data/words.txt").getLines().toList
println(list1)
//2、將每一行的資料按照|進行切分,並且進行扁平化操作
val flatlist: List[String] = list1.flatMap((e: String) => e.split("\\|"))
println(flatlist)
//3、根據元素進行分組
val groupList: Map[String, List[String]] = flatlist.groupBy((e: String) => e)
println(groupList)
//4、利用map中kv鍵值對可以計數的特點,進行計數
groupList.map((kv:(String,List[String]))=>{
val keys: String = kv._1
val counts: Int = kv._2.size
(keys,counts)
}).toList.foreach(println)
println("="*50)
/**
*使用鏈式呼叫進行簡寫
*/
Source.fromFile("scala/data/words.txt").getLines()
.toList
.flatMap((e:String)=>e.split("\\|"))
.groupBy((e:String)=>e)
.map((kv: (String, List[String])) => {
val keys: String = kv._1
val counts: Int = kv._2.size
(keys, counts)
})
.toList
.foreach(println)
/**
* 再進行簡化
*/
Source.fromFile("scala/data/words.txt")
.getLines()
.toList
.flatMap(_.split("\\|"))
.groupBy((e:String)=>e)
.map((kv:(String,List[String]))=>(kv._1,kv._2.size))
.toList
.foreach(println)
}
}