Scala

Scala

基础

数据类型

scala中的数据类型和java的数据类型对应关系:
* java:              scala:
* byte                Byte
* short               Short
* int                 Int
* long                Long
* float               Float
* double              Double
* boolean             Boolean
* char                Char

定义变量

在scala中定义一个变量,需要使用一个关键词:var
在scala中定义一个常量,需要使用一个关键词:val
整的写法:var 变量名:数据类型 = 值

字符串

//正常使用双引号构建字符串
//    var s1: String = "易政是世界上最帅的男人!"

    //    //使用三个一对双引号构建长字符串
    //    var sql1: String =
    //      """
    //        |select
    //        |*
    //        |from
    //        |students
    //        |where age>18
    //        |""".stripMargin
    
    * 在scala中字符串是如何做拼接的?
    //     * 1、使用+号拼接 这种拼接方式比较消耗性能
    //     * 2、使用StringBuilder
    //     * 3、前提:有一组序列,使用scala特有的函数 mkString
    //     * 4、使用scala特有的字符串传递方式 s"${变量}" 底层就是使用StringBuilder方式拼接的

运算符

同java

条件语句

/**
 * 条件语句
 * 选择语句:if
 * 循环语句:
 */
 //    if(age>18){
    //      println("成年了")
    //    }else{
    //      println("未成年")
    //    }
    
    * 1、在scala语言中,没有++或者--的语法  i+=1  i= i+1
     * 2、在scala语言中,不存在和java一样的普通for循环
     * 3、scala中的for循环写法不太一样
     
      //    for (e <- arr2) {
      //      println(e)
      //    }
      
     * while循环
     */
    //    var i:Int = 0
    //    while (i<arr2.length){
    //      println(arr2(i))
    //      i+=1
    //    }
    
        /**
     * 控制流程语句
     * 注意:在scala中没有break或者continue关键字使用breakable
     */
     
    breakable {
      for (e <- 1 to 10) {
        if (e == 5) {
          break // 底层实现是一个函数,抛出一个异常,终止程序运行
        }
        println(e)
      }
    }

读写文件

//Source.fromFil 底层是使用了字节输入流读取数据FileInputStream
val bs: BufferedSource = Source.fromFile("scala/data/words.txt")

    val bw = new BufferedWriter(new FileWriter("scala/data/words2.txt"))
    bw.write("易政真的是世界上最帅的男人!")

异常

  try {  
      /**
       * 也可以手动的抛出异常
       */
      val sc = new Scanner(System.in)
      print("输入除数:")
      val cs: Int = sc.nextInt()
      if(cs!=0){
        println(10/cs)
      }else{
        throw new ArithmeticException("您输入的除数是0")
      }
    }catch{
      //类似于sql语句中case when
      case e:ArithmeticException=>
//        println("除0异常")
          e.printStackTrace()
      case e:ArrayIndexOutOfBoundsException=>
        println("数组越界异常")
      case _ =>
        println("出现异常")
    }finally {
      //今后finally中的处理大部分情况下都与释放资源有关
      println("这是finally代码块")
    }

函数

/**
 * def: 定义函数或者方法的关键字
 * main: 是函数或者方法的名字,符合标识符的命名规则
 * args: 函数形参的名字
 * Array[String]: 参数的数据类型是一个元素为字符串的数组
 * =: 后面跟着函数体
 * Unit: 等同于java中的void 表示无返回值的意思
 *
 *
 * def main(args: Array[String]): Unit = {
 *
 * }
 * 在不同的地方定义,称呼不一样
 * 函数:在object中定义的叫做函数
 * 方法:在class中定义的叫做方法
 
 //如果方法调用的函数只有一个参数的时候,可以将.和小括号用空格代替调用
// 如果函数有返回值,且最后一句话作为返回值的话,return关键字可以不写
//
如果函数体中只有一句实现,那么大括号也可以不写
如果函数没有参数的时候,小括号省略不写
//函数或者方法必须定义在class或者object中

/**
 * scala中的函数也可以递归
 * 方法定义时,调用自身的现象
 *
 * 条件:要有出口,不然就是死递归
 */

类class

/**
 *  scala提供了一个非常好用的功能:样例类
 *  较少用户创建类所编写代码量,只需要定义成员变量即可,自动扩充成员变量,构造方法,重写toString方法
 */
 
 /**
 * 样例类中的成员变量,编译后默认是被jvm添加了final关键字,用户是改变不了的
 * 对于scala来说,默认是被val修饰的
 * 如果将来想要被改变,定义的时候需要使用var进行修饰
 */
 case class Teacher(name:String,age:Int,var like:String)

函数式编程

/**
 * scala中的函数式编程
 *
 * 面向对象编程:将对象当作参数一样传来传去
 * 1、对象可以当作方法参数传递
 * 2、对象也可以当作方法的返回值返回
 * 当看到类,抽象类,接口的时候,今后无论是参数类型还是返回值类型,都需要提供对应的实现类对象
 *
 * 面向函数式编程:将函数当作参数一样传来传去
 * 1、函数A当作函数B的参数进行传递
 * 2、函数A当作函数B的返回值返回
 *
 * 在scala中,将函数也当作一个对象,对象就有类型
 * 函数在scala也有类型的说法
 * 参数类型=>返回值类型
 */
 
 1.函数A作为函数B的参数定义
 2.函数当作参数传递
 3.函数当作返回值返回

函数的柯里化

* 面试题:什么是函数柯里化?
*  1、本身是一个数学界的一个名词,本意是原来一次传递多个参数,现在被改成了可以分开传递的形式,这种做法叫做柯里化
*  2、在scala中体现柯里化,指的是函数的返回值也是一个函数,将来调用时参数可以分开传递。
*  3、提高了程序的灵活性和代码复用性
*  4、在scala中也可以通过偏函数实现参数分开传递的功能
*/

集合

List

//获取List集合的长度
println(list2.size)
//可以直接通过索引下标获取元素
println(list2(0))
//scala推荐获取第一个元素的方式是调用head函数
println(list2.head)
println(list2.last)
    //根据指定的分隔符拼接元素
    println(list2.mkString("|"))
    
val resList1: List[Int] = list2.reverse //返回一个新的集合
    
val resList2: List[Int] = list2.distinct //返回一个新的集合(去重)

val resList3: List[Int] = list2.tail // 除去第一个,其余的元素返回一个新的集合
  
val resList4: List[Int] = list2.take(5) // 从左向右取元素,取若干个
      
val resList5: List[Int] = list2.takeRight(5) //取右边的几个,组成新的集合

//从第一个判断取数据,直到不符合条件停止
val resList10: List[Int] = list2.takeWhile((e: Int) => e % 2 == 0)

    val res1: Int = list2.sum // 元素必须是数值
    
    val res2: Int = list2.max

    /**
     * 高阶函数:
     * foreach: 将集合中的元素依次取出传入到后面的函数中
     * 注意:没有返回值的,要么就输出,要么就其他方式处理掉了
     */
    /**
     * 高阶函数:
     * map: 依次处理每一个元素,得到一个新的结果,返回到一个新的集合中
     */

    /**
     * 高阶函数:
     * filter: 保留符合条件的元素
     */

    /**
     * 高阶函数:
     * sortBy: 排序
     * sortWith: 两个数之间的关系排序
     */

    /**
     * 高阶函数:
     * flatMap: 扁平化
     */

    /**
     * 高阶函数:
     * groupBy: 分组
     */

Set

/**
 * set集合:scala中的Set集合也是不可变的,除了排序相关的函数以外,List集合有的高阶函数,Set集合也有
 */
 
     //List->Set
    val resSet4: Set[Int] = list1.toSet

    //Set->List
    val list2: List[Int] = resSet4.toList.sortBy((e:Int)=>e)

Mutable

/**
 * 通过观察api发现,不可变的集合是属于scala.collection.immutable包下的
 * 如果将来想要使用可变的集合,就要去scala.collection.mutable包下寻找
 */
     /**
     *  这里的可变List集合,上午说的功能函数,这里都可以调用
     */
    /**
     * 可变的Set集合
     */
    val hashSet1: mutable.HashSet[Int] = new mutable.HashSet[Int]()

Tuple

/**
 * 大小,值是固定的,根据创建的类来定,每个元素的数据类型可以是不一样,最高可以创建存储22个元素的元组
 */
     val t1: (Int, String, String, Int, String) = Tuple5(1001, "易政", "男", 17, "学习")

Map

//键是唯一的,键一样的时候,值会被覆盖
    //可以根据键获取值
    //    println(map1(1006)) // 小括号获取值,键不存在报错
    //    println(map1.get(1006)) // get函数获取,键不存在,返回None
    println(map1.getOrElse(1006, 0)) //根据键获取值,若键不存在,返回提供的默认值,默认值的类型可以是任意数据类型
    println("=" * 50)
    val keys: Iterable[Int] = map1.keys // 获取所有的键,组成一个迭代器
    for (e <- keys) {
      println(e)
    }
    
val values: Iterable[String] = map1.values // 获取所有的值,组成一个迭代器
    for (e <- values) {
      println(e)
    }

    //遍历Map集合第一种方式,先获取所有的键,根据键获取每个值
    val keys2: Iterable[Int] = map1.keys // 获取所有的键,组成一个迭代器
    for (e <- keys2) {
      val v: Any = map1.getOrElse(e, 0)
      println(s"键:${e}, 值:${v}")
    }

    //遍历Map集合第二种方式,先获取所有的键,根据键获取每个值
    for (kv <- map1) { // 直接遍历map集合,得到每一个键值对组成的元组
      println(s"键:${kv._1}, 值:${kv._2}")
    }
    
    //遍历Map集合第三种方式,先获取所有的键,根据键获取每个值
    map1.foreach((kv: (Int, String)) => println(s"键:${kv._1}, 值:${kv._2}"))

JDBC

/**
 *  jdbc的链接步骤
 *    1、注册驱动
 *    2、创建数据库链接对象
 *    3、创建数据操作对象
 *    4、执行sql语句
 *    5、如果第4步是查询的话,分析查询结果
 *    6、释放资源
 */
    //1、注册驱动
    Class.forName("com.mysql.jdbc.Driver")

    //2、创建数据库链接对象
    //jdbc:数据库名//host:port/数据库?xxx=xxx&xxx=xxx
    val conn: Connection = DriverManager.getConnection("jdbc:mysql://192.168.44.100:3306/studentdb?useUnicode=true&characterEncoding=UTF-8&useSSL=false", "root", "123456")

    //3、创建数据操作对象
    val preparedStatement: PreparedStatement = conn.prepareStatement("select id,name,age,gender,clazz from student where clazz=?")

    //4、执行sql语句
//    preparedStatement.setInt(1,23)
    preparedStatement.setString(1, "理科二班")
    val resultSet: ResultSet = preparedStatement.executeQuery()
    //5、如果第4步是查询的话,分析查询结果
    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")
    }

    //6、释放资源
    conn.close()

JSON

val lineList: List[String] = Source.fromFile("scala/data/stu.json").getLines().toList
val jsonStr: String = lineList.mkString("\r\n")

//使用fastjson包中的JSON类,将一个字符串转成json对象
//转成json对象之后,可以通过键获取值
//parseObject 将整体转成一个json格式数据
val jsonObj1: JSONObject = JSON.parseObject(jsonStr)
val s1: String = jsonObj1.getString("student_list")


//parseArray将一个"[{},{}]"变成一个元素是json对象的数组
val jSONArray: JSONArray = JSON.parseArray(s1)
var i = 0
while (i < jSONArray.size()) {
  val obj1: JSONObject = jSONArray.getJSONObject(i)
  val name: String = obj1.getString("name")
  val like: String = obj1.getString("like")
  println(s"${name}的爱好是${like}")
  i += 1
}

Scala to Java

//创建一个java中的集合
val array1: util.ArrayList[Int] = new util.ArrayList[Int]()
array1.add(11)
array1.add(22)
array1.add(33)
array1.add(66)

/**
 * 将java中的集合转成scala中的集合
 *
 * java中的集合本来是没有转换scala的功能,需要导入隐式转换
 * scala中的导包,可以在任意地方
 *
 */
import scala.collection.JavaConverters._
val list1: List[Int] = array1.asScala.toList
println(list1)

/**
 * scala中的集合转java的集合
 */
val list2: util.List[Int] = list1.asJava
println(list2)

Match(模式匹配)

/**
 * 模式匹配,就可以帮助我们开发的时候,减少代码量,让逻辑看起来更加清晰,以及可以避免一些异常
 * 语法:
 * 表达式 match {
 * case 值|[变量名:类型]|元组|数组|对象=>
 * 匹配成功执行的语句
 * case xxx=>
 * xxx
 * _  xxx=>
 * xxx
 * }
 *
 * 模式匹配中,如果没有对应的匹配,那么就报错!!!
 */
    /**
     * 可以匹配变量值
     */
//    var i: Int = 100
//    i match {
//      case 20 => println("该值是20")
//      case 50 => println("该值是50")
//      //      case 100=>println("该值是100")
//      case _ => println("其他值")
//    }
//
//    /**
//     * 匹配数据类型
//     */
//    var flag1: Any = true
//    flag1 match {
//      case _: Int => println("是Int类型")
//      case _: Boolean => println("是boolean类型")
//    }
//
//    /**
//     * 匹配元组
//     */
//    val t1: (Int, String, Int) = Tuple3(1001, "张三", 18)
//    t1 match {
//      case (a1: Int, b1: String, c1: Int) =>
//        println(s"学号:$a1, 姓名:$b1, 年龄:$c1")
//    }
//
//    /**
//     * 匹配数组
//     */
//    val array: Array[Any] = Array(1001, "李四", "男", 18, "理科一班")
//    array match {
//      case Array(id: Int, name: String, gender: String, age: Int, clazz: String) =>
//        println(s"学号:$id, 姓名:$name, 性别:$gender, 年龄:$age, 班级:$clazz")
//    }

模式匹配的应用1:避免异常
模式匹配的应用2:简化代码
    stuArrayList.map{
      case Array(id: String, name: String, gender: String, age: String, clazz: String)=>
        (id, name, gender, age, clazz)
    }.foreach(println)

implicit(隐式转换)

/**
 * 隐式转换
 * 1、隐式转换函数
 * 2、隐式转换类
 * 3、隐式转换变量
 *
 * 将一个A类型将来会自动地转换成另一个B类型,类型可以式基本数据类型,也可以是引用数据类型
 *
 * 显式转换
 */
函数
//    implicit def implicitFun1(s: String): Int = {
//      return Integer.parseInt(s)
//    }

    //    def fun1(s: Int): Int = {
    //      return s + 1000
    //    }
    
        //    println(fun1("300"))
类
正常调用
//    val demo1 = new Demo12("scala/data/students.txt")
//    val stuList: List[String] = demo1.show1()
使用隐式转换
//    val stuList: List[String] = "scala/data/students.txt".show1()
//    val scoreList: List[String] = "scala/data/scores.txt".show1()

    "易政".f()

  }

  //`implicit' modifier cannot be used for top-level objects
  //implicit class Demo12(path: String) {
  //implicit使用的地方,不能超过object作用域
  
  implicit class Demo12(path: String) {
    def show1(): List[String] = {
      Source.fromFile(path).getLines().toList
    }

    def f()={
      println(s"好好学习,天天向上!$path")
    }
  }
隐式转换变量
    //定义一个隐式转换参数
    def fun1(a1: Int)(implicit a2: Int): Int = a1 + a2

    //定义一个隐式转换变量
    implicit var i1: Int = 1000

    val res1: Int = fun1(100)
    println(res1)
posted @ 2024-08-02 21:46  易政  阅读(100)  评论(0)    收藏  举报