一門多正規化的程式語言Scala學習收尾-函式的使用

shmil發表於2024-08-23

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)

  }
}

相關文章