scala快速入门

  1. 变量与常量的声明

    val 用来声明变量,但这个变量声明时必须初始化,否则会报错,并且初始化后就不能再更改其值。因此val声明的变量被称为常量。而var声明的变量可以重复使用,任意修改,并且以最后一次修改的值为准。书上说用var声明变量可以不用初始化,但是我试验是错的。

    val 常量名:数据类型 = 初始值

    var 变量名:数据类型 = 初始值


    如上,声明常量不初始化报错;

    如上,初始化后修改值报错。

    关于书上讲到的var声明变量可以不初始化,我试验是错的。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jnVgvUj2-1656246754569)(C:/Users/dell/AppData/Roaming/Typora/typora-user-images/image-20220622191305135.png)]

  2. scala没有像c或java那样有++,–操作。需要使用+=或者-=来实现对应功能。

  3. Scala的9种基本数据类型Byte、Short、Int、Long、Float、Double、Char、Boolean和String。且Scala所有数据类型的第一个字母都必须大写。在Java中用void修饰创建一个无返回值的方法,而Scala中没有void关键字,而是用Unit表示无返回值

  4. Scala的if/else语法结构和Java一样。不过,**在Scala中if/else表达式有值,这个值就是跟在if或else之后的表达式的值。**就是说if-else不单单是一个逻辑判断语句,还可以带值。

    val x = 0
    val s = if (x > 0) 1 else -1//s的值为-1
    

  5. scala中的循环

    • scala的while循环和do while循环和c类似。这种重点讲一下for循环。

    • for循环不像c样 for(初始化变量;检查变量是否满足某条件;更新变量),而是有如下形式:

      1. for(x < -Range )方式 ,“<-”用于为变量x赋值。**Range可以是一个数字区间,如i to j ,或者 i until j。**区别就是i to j表示的区间是[i,j],i until j表示的区间是[i,j)

        for (i <- 1 to 5) printf("%d ",i)
        for (i <- 1 until 5) printf("%d ",i)
        

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ue4UwHyL-1656246754570)(C:/Users/dell/AppData/Roaming/Typora/typora-user-images/image-20220623191549507.png)]

      1. 对数组或者集合的遍历,还可以更简洁,操作如下

        val list1=List(3,5,2,1,7)//使用List创建一个集合
        for(x <- list1) //遍历集合,将集合list1的每一个元素通过 <- 赋值给x进行输出
          printf("%d ",x)
        

        [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HSjqM1q8-1656246754571)(C:/Users/dell/AppData/Roaming/Typora/typora-user-images/image-20220623192042671.png)]

  6. 数组
    数组是Scala中常用的一种数据结构,是一种存储了相同类型元素的顺序数据集合。在Scala中数组有两种:定长数组变长数组

    1. 定长数组:是一个长度不变的数组,声明后就不能删除或者增加元素。

      var z:Array[String] = new Array[String](3)//声明长度为3的字符串类型的数组。默认会初始化为null。z后面的类型可以省略,即可以写成如下形式
      var z = new Array[String](3)
      //如果希望自己初始化,则不需要new,直接使用Array即可
      var nums = Array(11,22,33,44)
      var z = Array("TOM","Cat")
      

      注意:**在Scala中使用(index)而不是[index]来访问数组中的元素。**注意和其他语言的区别。数组开始下标为0.

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DyjbQh3l-1656246754571)(C:/Users/dell/AppData/Roaming/Typora/typora-user-images/image-20220623193010298.png)]

      如上,若使用了[]来访问数组,则报错。

    2. 变长数组

      使用ArrayBuffer声明一个数组长度可变的变长数组.使用ArrayBuffer创建变长数组之前,需要先导入scala.collection.mutable.ArrayBuffer包。

      import scala.collection.mutable.ArrayBuffer
      val arr1 = ArrayBuffer[Int]()  //括号里为空则表示定义了长度为0变长数组
      arr1 +=1                    //为数组arr1添加元素1
      arr1+=(7,9,3,5)          // 一次添加多个元素
      //使用+= 添加元素
      

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JI18DANS-1656246754571)(C:/Users/dell/AppData/Roaming/Typora/typora-user-images/image-20220623193830707.png)]

      如果要在要把变长数组ArrayBuffer转换为定长数组Array,则使用toArray(),反之,如果要在要把定长数组Array转换为变长数组ArrayBuffer,则使用toBuffer

      //将上面创建的边长数组arr1转换为定长数组arr2.转换为定长数组后就不能直接增加或者删除元素了
      var arr2 =  arr1.toArray
      

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vEERxGHz-1656246754572)(C:/Users/dell/AppData/Roaming/Typora/typora-user-images/image-20220623194516371.png)]

    3. 数组的遍历
      前面讲过,对于数组和集合这些数据结构,直接通过变量数组名即了遍历全部元素

      for( x <- arr2) print(" "+x)//遍历刚刚由动长数组转换为定长数组的arr2
      

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hpt4j3uu-1656246754572)(C:/Users/dell/AppData/Roaming/Typora/typora-user-images/image-20220623194711047.png)]

      也可以通过下边遍历。数组有一个length属性可以获取长度。

      for( i <- 0 until arr2.length) print(" "+arr2(i))
      

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mc1UucAV-1656246754573)(C:/Users/dell/AppData/Roaming/Typora/typora-user-images/image-20220623195019188.png)]

      这里出现了2个考点,一是until表示的区间是[)左闭右开.而to表示的是[]左右均闭。而是数组和其他语言一样,下标都是从0开始到length-1。而scala的元组的下标是从1开始。(这里可能考选择,请留意)

    4. 数组的一些操作

      • map()映射: map()是通过一个函数重新计算数组中的所有元素,并且返回一个相同数目元素的新数组。

        var arr = Array(1,2,3,4) //创建数组arr并初始化
        arr.map(x => x * 5) 调用数组对象的map()方法,每个元素乘以5
        

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dffluQQv-1656246754573)(C:/Users/dell/AppData/Roaming/Typora/typora-user-images/image-20220623195604773.png)]

    5. foreach()遍历数组中的元素

      var arr = Array("Hello Beijing","Hello Shanghai")
      arr.foreach(x => println(x))     //遍历输出数组中的元素
      

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kQqapFyn-1656246754573)(C:/Users/dell/AppData/Roaming/Typora/typora-user-images/image-20220623200315001.png)]

​ 还有诸如arr.min,arr.max,arr.sum等等操作,参考数P30.

  1. List列表和Set集合与数组声明等基本类似,只是一些操作方法不一样。这里看书或者ppt。

  2. 映射(Map)

    映射(Map)是一系列键值对的集合,所有值都可以通过键来获取,并且Map中的键都是唯一的。Map也叫哈希表(Hash tables)。和数组一样,Map也有两种类型,可变与不可变两种,默认创建的都是不可变映射,如果要创建可变映射,需要导入scala.collection.mutable.Map包。

    1. 不可变映射
      使用"->"方式创建或者使用使用(k, v)方式创建

      val NameGrades1=Map("LiHua"->89,"LiuTao"->91,"YangLi"->88)
      val NameGrades1 = Map(("LiHua",89),("LiuTao",91),("YangLi",88))
      

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XPMVPFoW-1656246754574)(C:/Users/dell/AppData/Roaming/Typora/typora-user-images/image-20220623201137330.png)]

    2. 基本操作
      keys:返回所有的键
      values :返回所有的值
      get(key):返回指定key对应的值

      NameGrades1.keys
      NameGrades1.values
      

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hZ3TXmtg-1656246754574)(C:/Users/dell/AppData/Roaming/Typora/typora-user-images/image-20220623202710852.png)]

      +添加元素
      -删除元素

      //添加张三
      NameGrades1+(("zhangsan",33))
      //也可以
      NameGrades1+("zhangsan"->33)//注意括号
      

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W1YjtArL-1656246754574)(C:/Users/dell/AppData/Roaming/Typora/typora-user-images/image-20220623203245865.png)]

    3. 遍历map

      for((k,v) <- NameGrades1) print(s"key:$k,value:$v") //前面括号(k,v)命名随意,但是后面的$跟的要跟定义的名字一样。 前面必须 是 s"key:xx,value:xx"才能输出,为固定格式
      

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f5Cjinno-1656246754575)(C:/Users/dell/AppData/Roaming/Typora/typora-user-images/image-20220623203814298.png)]

      也可以使用foreach遍历:

      NameScores.foreach(x => println(s"key: ${x._1},value: ${x._2}"))//(key,value)形式本身是一个二元组。所以通过._xx来遍历也是可行的。
      

      这里要注意的是,元组的下标是从1开始的,且访问元素的形式是xxx._xx

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c83Lz8nx-1656246754575)(C:/Users/dell/AppData/Roaming/Typora/typora-user-images/image-20220623204153918.png)]

      如上,访问元组的方式以及下标不能为0。这里顺便把元组这种数据结构讲了。声明就直接使用var xxx = (x,x,x,x)

  3. 函数
    scala的函数最大的一个区别就是函数可以像任何其他数据类型一样被传递和操作,可以像定义变量那样去定义一个函数。简单来说,函数可以当作变量一样来对待

    1. 有返回值的函数声明

      def 函数名([参数列表]):[函数的返回值类型] = {
         函数体
         return [返回值表达式]
      }
      //举例
      def addInt(a: Int,  b: Int): Int = {
         var total: Int = a + b
         return total
      }
      addInt(1,2)//输出3
      

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jd8BuIgP-1656246754575)(C:/Users/dell/AppData/Roaming/Typora/typora-user-images/image-20220623204821082.png)]

      //但在scala当中,函数有返回值时,通常不写return,函数体的最后一个表达式的值就是函数的返回值,且此时函数返回类型也可省略
      def addInt(a: Int,  b: Int) = {a + b}
      addInt(1,2)//输出3
      

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C06fbqQ3-1656246754576)(C:/Users/dell/AppData/Roaming/Typora/typora-user-images/image-20220623210220197.png)]

    2. 无返回值的函数声明

      //1是使用Unit显示标识函数无返回值,2是去掉等号,就标时函数无返回值
      def returnNone(a: Int,  b: Int): Unit = {
          print(a+b)
      }
      def returnNone(a: Int,  b: Int):{
          print(a+b)
      }
      

      在这里插入图片描述

      这里补充一个小点,前面说了函数可以像变量一下定义,所以函数像变量一样具有类型

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Gd0v9Nc3-1656246754576)(C:/Users/dell/AppData/Roaming/Typora/typora-user-images/image-20220623210845415.png)]

    3. 匿名函数(重点掌握)
      Scala匿名函数是使用箭头“=>”定义的,箭头的左边是参数列表,箭头的右边是表达式,表达式的值即为匿名函数的返回值。

      //注意与普通函数的区别
      def f1(a:Int,b:Int)={a+b}
      //上述函数等价的匿名函数为
      (a:Int,b:Int) => a+b //当函数体只有一条语句时,大括号可以省略
      

      前面说了,在scala中函数可以像定义变量一样使用

      var value = (a:Int,b:Int) => a + b//定义一个匿名函数并赋值给value
      value(1,2)//调用
      

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IjhAAJbP-1656246754576)(C:/Users/dell/AppData/Roaming/Typora/typora-user-images/image-20220623210703451.png)]

  4. 在Scala中,通过class关键字定义类,语法格式如下:
    class 类名{
         //此处定义类的字段和方法
    }
    //一旦定义了类,就可以用关键字new根据类模板创建对象。
    
    //类的定义和java类似。只是如果想要初始化类的成员变量。实在类名后传到参数,而java是通过构造函数初始化,这一点要注意
    class Point(xc: Int, yc: Int) {
       var x: Int = xc               //定义可读写属性
       var y: Int = yc               //定义可读写属性
       def move(dx: Int, dy: Int) : Unit ={  //定义方法
          x = x + dx
          y = y + dy
          println ("x 的坐标点: " + x);
          println ("y 的坐标点: " + y);
       }
    }
    new Point(2,2).move(3,3) //new一个类并调用move方法,这跟java完全一样。
    

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值