Scala

1.Scala基础

 /**            Scala
   * Scala在Java的基础上进行开发,使用Jvm解释器,
   * 语言上比Java更加精炼,做到了纯面向对象编程
   * Scala中每一行代码都是一个表达式
   * 与Java不同的是,每行的末尾不需要写;
   */


  //1.变量和常量的声明
  //变量在声明时可以使用_来代替但是必须指明变量类型
  //也可以不用指明变量类型但是要给出具体值,后续的值是可以改变的
  var A:String = _
  var B = 5
  //常量通常一经声明就不允许在被改动,通常做全局常量
  val HOST = "127.0.0.1"
  //特殊的,这也是一个表达式,独占一行,但是没有实际意义
  5
  "张三"
  0.2f

  //2.代码块
  //使用一对{}包起来的一段程序叫做一段代码块
  //代码块中可以进行逻辑处理,代码块的最后一行内容作为代码块的返回值
  //代码块可以被赋值
  var A = {
    var i = 1
    i += 1
    i
  }

  //3.方法
  //Scala中方法的声明语法
  //def 方法名(参数名:参数类型):返回值类型={
  //        方法体
  // }
  def getValue(value:Int): Unit ={
    val i = value.asInstanceOf[String]
    i
  }

  //4.函数
  //有名字 有参数 有返回值的一段代码块
  //参数:函数的参数可以是任意类型,也可以是一个函数
  //区别与方法就是看修饰对象,修饰对象就是方法,其他的就是函数
  def calc(x: Int, y: Int, op: (Int, Int) => Int): Unit = {
    op(x, y)
  }
  calc(1, 2, (a, b) => a + b)
  //二元函数如果参数的声明顺序与使用顺序一致且每个参数只使用了一次可以用_代替
  calc(1, 2, _ + _)
  //函数作为其他函数的返回值
  //函数的柯里化:所有函数都可以被书写成为一个参数的函数
  //在开发使用时本质上就是将函数声明的参数列表拆分为多个,将不功能的参数放在不同的参数列表中进行业务隔离,避免多个参数传参时出现混淆


//5.类
//在类中与Java相同可以声明属性和方法
//必须在实例化之后才可以进行调用
//为了弥补缺少static的缺陷在创建对象时可以创建成单例对象object
//Scala中类的主构造器与类的声明位置重合,类名后面就是类的主构造器的参数列表
//主构造器的参数列表中,如果使用val/var声明的时候,直接作为类的成员属性
//Scala中主构造器只有一个,如果想要进行构造器的重载可以使用辅助构造器
//辅助构造器就是一系列使用def声明 名字叫this的方法
//所以的辅助构造器必须直接或者间接的调用主构造器
//如果一个Class与一个object名字完全相同并且声明在同一个Scala文件当中
//此时Class与object互为伴生关系
//object中的可以用类名.的方式调用,而Class中的属性和方法必须实例化之后才可以使用
//互为伴生对象的两个类,成员之间的属性和方法可以相互调用
class Student(var birthday:String) {
  private var name:String = _
  //可以添加注解在调用的时候使用get,set方法
  @BeanProperty
  var age:Int = _
  //在val声明的时候必须给定初始值
  val gender:String = "男"

  def play(name:String): Unit ={
    println(name + "打游戏")
  }
  def study(): Unit ={
    println("好好学习")
  }
  def this(name:String){
    this(birthday)//调用主构造器
    this.name = name
  }
  def this(name:String,age:Int){
    this(name)//间接调用主构造器
    this.age = age
  }
}
object Student{
  def Eat(): Unit ={
    var school:String = "北京大学"
    println("能吃")
  }
}

  //6.特质
  //Scala中trait与Java中的interface类似
  //是为了解决面向对象中不允许进行多继承的语法而设计的结构
  //本质上与抽象类类似,可以包含多抽象方法或者实现方法
  //trait支持多实现也支持动态混入

  val human = new human() with Gamer
  val properties = new Properties() with Gamer
  properties.play()

  class human(){
    def study(): Unit ={
      println("刻苦学习")
    }
  }
  
  trait Gamer{
    def play(): Unit ={
      println("打游戏")
    }
  }

  //7.apply与update
  //apply是一系列特殊方法声明在object中
  //调用时可以直接使用对象名(参数)调用
  //根据传入的参数值不同从而自行判断调用那个方法
  //案例类的原理就是利用封装了apply
  //Scala中数组的取值arr.apply(索引),赋值arr.update(索引,值)
  //基于apply的隐式调用就可以将繁琐的调用改成 取值arr(索引) 赋值arr(索引) = 值
  object Utils {
    def apply(L: Long): String = {
      val format = new SimpleDateFormat("yyyy-MM-dd")
      format.format(L)
    }
  
    def apply(s: String): Long = {
      val format = new SimpleDateFormat("yyyy-MM-dd")
      format.parse(s).getTime
    }
  }
  
  Utils(System.currentTimeMillis())
  Utils("2020-06-12")
  
  //案例类
  case class Person(var name: String, var age: Int)
  
  val person = Person("张三", 22)
  
    //8.option和异常处理
    //使用getOrDefault如果拿不到值则使用默认的
    //如果key不存在,直接返回null可能造成空指针异常
    //所以Scala设计了Option类
    //option有两个子类
    // None 在无返回值时 返回None实例
    // Some 在有返回值时  返回Some实例并将需要返回的对象封装在Some中
    val map = new util.HashMap[String, Int]()
    val i = map.getOrDefault("K1", 0)
    println(i)
  }

  try {
    var stream = new FileInputStream("")
  } catch {
    case e: NullPointerException => //要执行的操作
    case e: ArrayIndexOutOfBoundsException => //要执行的操作
    case e: Exception => //要执行的操作
  } finally {
    //要执行的操作
  }

2.Scala特殊语法

	//for推导式
    //Java中的for
    //for(循环执行的语句;循环体执行的条件;循环后执行的语句)

    //Scala中的for
    //for(变量名 <- 集合){
    // 循环体
    // }
    //生成器每次执行 将集合中的一个元素赋值给标变量并执行
    val arr = new Array[Int](5)
    for (e <- arr) {
      println(e)
    }

    //生产一个1-5的数组
    val array = Array(1 to 5)
    //取到数组中所有元素的下标
    val indices = array.indices

    //Scala去除了break关键字,可以使用以下语法
    //    Breaks.breakable{
    //      循环体{
    //        要执行的操作
    //        Breaks.break
    //      }
    //    }

    //Scala中的守卫
    //if声明在for表达式中
    //if后的表达式不用写()
    //满足if条件的值进入循环体
    for (i <- 1 to 10 if i % 2 == 0) {
      println(i)
    }

    //收集器
    //收集循环过程中满足计算的结果收集到集合中进行返回
    //yield后面还可以对拿到的数进行处理
    val ints = for (i <- 1 to 10 if i > 5) yield i


    //了解数据结构和时间空间复杂度

3.Scala控制结构

    //1.if-else
    //语法:
    //  if (条件){
    //    执行操作
    //  }else{
    //    执行操作
    //  }
    //当判断条件只有一行,且两个返回类型相同时可以对if-else进行赋值操作
    val a = 1
    val b = 2
    val c = if (a<b) a else b
  
    //2.while
    //Scala与Java中的语法相同
    //Scala中while循环的返回值固定为Unit
    //do-while区别与while是在循环开始必须要先先执行一次
    var i = 1
    val unit = while(i<=5){
      println(i)
      i+=1
    }

4.Scala数据结构与集合

	//1.Array定长数组
    //创建
    val ints = new Array[Int](5)
    //取值
    val i = ints(3)
    //赋值
    ints(4) = 5
    //遍历
    for (e <- ints) {
      println(e)
    }

    //2.ArrayBuffer可变长度数组
    //创建
    val buffer = new ArrayBuffer[Int]()
    val buffer1 = ArrayBuffer[Int]()
    //赋值
    buffer.append(1)
    buffer += 2
    //按照下标删除元素
    buffer.remove(1)
    //取值
    val i1 = buffer(2)
    println(i1)
    //遍历
    for (i <- buffer.indices) {
      buffer1 append buffer(i) + 1
    }
    //map映射
    //将buffer1中的元素取出做操作映射到新的buffer2中原buffer1中的元素不受影响
    val buffer2 = buffer1.map(x => x + 1)

    //Java与Scala中数组的相互转换
    //导入相关包
    //Scala中import语句没有书写限制,可以定义在类或方法中
    val java = buffer.asJava
    val scala = java.asScala

    //3.tuple元组
    //用于灵活创建多个不同类型的元素
    //创建
    val tuple = ("张三", 1)
    //取值
    val value1 = tuple._1
    val value2 = tuple._2

    //4.map映射
    //Scala中使用二元组存储KV
    //创建
    val map = new mutable.HashMap[String, String]()
    //赋值
    map.put("k1", "v1")
    map += (("k2", "v2"))
    //取值
    //取得到
    map.get("k1")
    //取得到取,取不到输出默认值
    map.getOrElse("k1", "222")
    //遍历
    for (t <- map){
      t._1  //二元组的K
      t._2  //二元组的V
    }
    //判断k1是否存在
    map.contains("k1")

    //5.队列和栈
    //Queue队列
    //先进后出
    //创建
    val queue = new mutable.Queue[Int]()
    //入列
    queue += 2
    queue += 3
    queue += 4
    //出列
    queue.dequeue()
    //Stack栈
    //先进后出
    //创建
    val stack = new mutable.Stack[Int]()
    //压栈
    stack.push(1)
    stack.push(2)
    stack.push(3)
    //出栈
    stack.pop()

    //6.列表
    //Scala中List是一个不可变集合的一个实现类
    //创建
    val list = List(1, 2, 3)
    //拼接
    //在list的尾部拼接并创建新的list
    val list1 = list :+ 4
    //在list的头部拼接并创建新的list
    val list2 = 0 +: list
    //两个list拼接
    val list3 = list1 ++ list2
    //空列表
    val nil = Nil
    //遍历
    for (e <- list){
      println(e)
    }

5.Scala集合算子

1.基本算子

	val list1 = List("Harry", "waited", "for", "the", "rest", "of", "the", "gang", "to", "move", "on", "before", "setting", "off", "again")
    //返回列表中的第一个元素
    println(list1.head)
    //较为安全的返回:如果集合中存在元素返回Some类型,如果不存在则返回None类型
    println(list1.headOption)
    //返回列表中的最后一个元素
    println(list1.last)
    //较为安全的返回:如果集合中存在元素返回Some类型,如果不存在则返回None类型
    println(list1.lastOption)
    //返回除第一个意外的所有元素
    println(list1.tail)
    //返回除最后一个以外所有的元素
    println(list1.init)
    //返回集合的长度
    println(list1.length)
    //判断集合是否为空
    println(list1.isEmpty)
    val list2 = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    //返回集合中所有元素的和
    println(list2.sum)
    //返回集合中所有元素的积
    println(list2.product)
    //返回集合中所有元素的最大值
    println(list2.max)
    //返回集合中所有元素的最小值
    println(list2.min)
    //count中传入一个表达式 从list2中拿值进行验证如果满足表达式则计数 最后返回满足表达式的个数
    println(list2.count(_ % 2 != 0))
    //forall中传入一个表达式 如果list2中所有元素都满足 则返回true 否则返回false
    println(list2.forall(_ > 0))
    //exists中传入一个表达式 如果list2中只要有一个元素满足该表达式 则返回true 如果都不满足则返回false
    println(list2.exists(_ % 5 == 0))
    //filter中传入一个表达式 将满足所有这个表达式的元素装在一个List中进行返回
    println(list2.filter(_ % 3 == 0))
    //filter中传入一个表达式 除满足这个表达式以外的所有元素装在一个List中进行返回
    println(list2.filterNot(_ % 3 == 0))
    //partition中传入一个表达式 将满足该表达式的元素放在一个集合当中 剩余的元素放在另一个集合当中进行返回
    println(list2.partition(_ > 5))
    //从list2中由左向右拿到前三个元素
    println(list2.take(3))
    //从list2中由右向左拿到后三个元素
    println(list2.takeRight(3))
    //从list2中拿取元素当取到的一个不满足此条件的元素时,将之前收集到的元素全部返回
    println(list2.takeWhile(x => x < 6))
    //将list2升序排序
    println(list2.sorted)
    //将list2降序排序
    println(list2.sorted.reverse)
    //将满足表达式的元素删除,剩下的元素以集合的形式返回
    println(list2.dropWhile(x => x < 6))
    //以5为分界点将list2分解成两段
    println(list2.splitAt(5))
    //返回集合中每个元素的长度并放入一个新的集合返回
    println(list1.map(w => w.length))
    //返回list1集合中每个元素的首字母
    list1.foreach(w => print(w.head))

2.高级算子

val list = List("Harry", "waited", "for", "the", "rest", "of", "the", "gang", "to", "move", "on", "before", "setting", "off", "again")

    //map()
    //1.声明
    //def map[B, That](f: A => B): That = {
    //2.参数
    //  f 是一个一元函数
    //  f 的参数是原集合的元素类型
    //  f 的返回值是任意自定义类型
    //3.返回值
    //  map的返回值是一个原集合类型相同 泛型为f的返回值类型的集合
    //4.作用
    // 将原集合中的所有元素 都传入函数中将函数的返回值放在一个新的集合中返回
    //5.Example
    val len = list.map(x => x.length) //将list元素集合映射成一个元素长度集合

    //foreach()
    //1.声明
    //def foreach [U](f: A => U): Unit = {
    //2.参数
    //  f 是一个一元函数
    //  f 的参数是原集合的元素类型
    //  f 的返回值是任意自定义类型
    //3.返回值
    //  固定返回Unit
    //4.作用
    //  依次将原籍和元素传入f,foreach通常用来封装打印输出操作,本身不负责收集f的处理结果
    //5.Example
    list.foreach(w => print(w.head)) //打印输出list中元素的首字母

    //flatmap()
    //1.声明
    //def flatMap [B,That](f: A => GenTraversableOnce(👈集合的超类)[B]): That = {
    //2.参数
    //  f 是一个一元函数
    //  f 的参数是原集合的元素类型
    //  f 的返回值必须是集合类型
    //3.返回值
    //  与原集合的类型相同 泛型是f的返回值的泛型集合
    //4.作用
    //  将使用map相同操作获得的二维集合压扁为一维集合,通俗来说就是就二维集合拆解成一维集合
    //5.Example
    val resMap = new mutable.HashMap[Char, Int]()
    list.flatMap(x => x.toCharArray).foreach(c => resMap.put(c, resMap.getOrElse(c, 0) + 1)) //打印输出list中字母出现的个数以(Char,Int)的形式输出

    //collect()
    //1.声明
    //def collect[B, That](pf : PartialFunction[A, B])( bf : [List[A], B, That]) : That = {
    //2.参数
    //  pf 是偏函数
    //3.返回值
    //  返回值是一个集合泛型与apply的泛型一致
    //4.作用
    // 将原集合中的所有元素 都传入函数中做统计 将统计结果返回
    //5.Example
    val pf = new PartialFunction[String, Char] { //偏函数
      //判断输出的元素是否满足需要处理的条件
      override def isDefinedAt(x: String): Boolean = {
        x.length == 3 || x.length == 4
      }

      //将isDefinedAt返回true的元素传入apply进行处理返回处理的结果
      override def apply(v1: String): Char = {
        val length = v1.length
        if (length == 3) v1.head
        else v1.last
      }
    }

    val res5: Any = list.collect(pf) //获取长度为3单词的首字母 长度为4单词的尾字母

    //由于每次使用collect需要实现偏函数书写太繁琐,可以使用模式匹配的方式
    //   collect{
    //case 变量名 守卫=>执行操作
    //   }
    val ree6 = list.collect {
      case x if x.length == 3 => x.head
      case x if x.length == 4 => x.last
    }

    val list1 = List(4, 2, 3, 9, -5, 6)
    //聚合算子
    //reduce==reduceLeft reduceRight
    //1.声明
    //  def reduceLeft(op: (B, A) => B): B =
    //  def reduceRight(op: (A, B) => B): B =
    //2.参数
    //  op是一个二元函数
    //  op的第一个参数是任意类型
    //  op的第二个参数原集合的元素类型
    //3.返回值
    //  返回值是op的返回值类型
    //4.作用
    //  将集合中的元素 按照从左到右  或者从右到左的顺序进行依次聚合
    //  每次聚合的结果作为下一次聚合的一个参数
    //5.Example
    val i = list1.reduceLeft(_ - _) //输出为-11
    val j = list1.reduceRight(_ + _) //等同于Sum 输出为19

    //fold foldLeft foldRight
    //1.声明
    //def foldLeft(z: B)(op: (B, A) => B): B = {
    //2.参数
    //fold提供了两个柯里化参数列表
    //第一个参数列表用于声明一个集合的初始值
    //第二个参数列表用于声明聚合过程的逻辑
    //3.作用
    //将集合中的元素按照自己的意愿设计操作执行
    //4.Example
    println(list1.foldLeft((0, 0))((b: (Int, Int), a: Int) => (b._1 + a, b._2 + 1)))  //返回一个二元组(19,6)

    //zip 缝合函数
    //1.作用
    //将两个集合对应下标的元素两两组合成一个二元组放在一个新的集合中返回
    //2.Example
    val A = List("a", "b", "c")
    val B = List(1, 2, 3, 4)
    println(A zip B)  //List((a,1), (b,2), (c,3))

6.案例类模式匹配

//案例类也称样例类
    //使用case class声明的类称为案例类
    //1.案例类的主构造器中的参数 默认使用val修饰作为类的不可变成员属性,也可声明成var可变属性,但不推荐
    //2.案列类编译时会自动添加伴生对象和全参的apply,用于类的对象创建
    //3.案例类编译时会自动重写tostring方法便于对象的打印
    //4.案例类编译时会自动添加copy方法用于对象的克隆
    //5.案例类编译时会自动添加伴生对象的全参unapply(提取器)方法,用于模式匹配

    case class stu(name:String,age:Int)

    //模式匹配
    //match case
    //需要注意:从上到下优先匹配符合条件的操作
    //语法
    //对象 match {
    //    case 变量名 if 条件 => { 匹配成功执行的操作  }
    //    case 变量名 if 条件 => { 匹配成功执行的操作  }
    //    case 变量名 if 条件 => { 匹配成功执行的操作  }
    // }
    
    //对象 match {
    //    case 案例类1 => { 匹配成功执行的操作  }
    //    case 案例类2 => { 匹配成功执行的操作  }
    //    case 案例类3 => { 匹配成功执行的操作  }
    // }

    //对象 match {
    //    case 值1 => { 匹配成功执行的操作  }
    //    case 值2 => { 匹配成功执行的操作  }
    //    case 值3 => { 匹配成功执行的操作  }
    //    case _  => { 匹配成功执行的操作  }
    // }

    //Example
    val i = Random.nextInt(10)
    val res = i match{
      case 0 => "zero"
      case 1 => "one"
      case 2 => "two"
      case _ => "Other"
    }
    println(res)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值