Scala学习笔记(三)

作者: fengzhizi715 | 来源:发表于2017-02-05 00:14 被阅读1811次

    Scala的基础语法

    继上一篇的基础语法之后,我又整理了一些个人学习过程中认为比较重要的语法。

    1. if/else 表达式

    1.1 替代三目运算符

    先用 Java 来写一段三目运算符的代码

    int i = 10;
    int j = i>5?i:5
    

    Scala 由于没有 Java 的三目运算符(?:),不过好在可以用 if/else 表达式替代它。

    scala> val i = 10
    i: Int = 10
    
    scala> val j = if (i>5) i else 5
    j: Int = 10
    

    上面的代码,还可以写成

    scala> val i = 10
    i: Int = 10
    
    scala> var j =0
    j: Int = 0
    
    scala> if (i>5) j = i else j=5
    
    scala> println (j)
    10
    

    不过,这种写法变量 j 需要定义成 var,因为 val 的变量一旦定义不能被改变略嫌麻烦 , 所以第一种写法会更好。

    1.2 混合类型表达式

    scala> val i = 10
    i: Int = 10
    
    scala> val j = if (i>5) "String express" else 5
    j: Any = String express
    
    scala> println(j)
    String express
    

    一般三目运算符肯定是返回同一种类型,但是上述的代码在 if 和 else 里既有String类型又有Int类型。所以,返回的是两个类型的公共超类型Any。

    2. 占位符_

    Scala 可以把下划线“_”当做一个或多个参数的占位符,第一个下划线代表第一个参数,第二个下划线代表第二个,以此类推。只要每个参数在函数文本内仅出现一次。

    先看一段 Java 的代码,它将集合的每个元素都乘以2再打印出来。

    Integer[] arrays = {1,2,3,4,5};
    List<Integer> list = Arrays.asList(arrays);
    list.stream().map(it->it*2).forEach(System.out::println);
    

    再用占位符来简化上述的 Java 代码

    scala> val list = Array(1,2,3,4,5)
    list: Array[Int] = Array(1, 2, 3, 4, 5)
    
    scala> list.map(_*2).foreach(println)
    2
    4
    6
    8
    10
    

    通过对比,显然 Scala 的代码更加简洁。

    再来一个例子:多个占位符

    scala> val f1 = (x:Int,y:Int) => x+y
    f1: (Int, Int) => Int = $$Lambda$1011/349978505@1706a5c9
    
    scala> f1(1,2)
    res0: Int = 3
    

    用两个占位符来简化上面的代码。

    scala> val f2 = (_:Int)+(_:Int)
    f2: (Int, Int) => Int = $$Lambda$1034/74606989@7b7683d4
    
    scala> f2(1,2)
    res1: Int = 3
    

    3. Array 、 ArrayBuffer 以及多维数组

    Scala 的数组包括定长数组 Array,以及不定长数组 ArrayBuffer。

    3.1 Array

    scala> val nums = new Array[Int](10) // 所有元素初始化为0
    nums: Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
    
    scala> val strings = new Array[String](10) // 所有元素初始化为null
    strings: Array[String] = Array(null, null, null, null, null, null, null, null, null, null)
    
    scala> val names = Array("tony", "cafei", "aaron")
    names: Array[String] = Array(tony, cafei, aaron)
    
    scala> names(0)
    res2: String = tony
    

    一旦初始化 Array ,只能修改 Array 中的元素,不能增加或者删除元素。

    3.2 ArrayBuffer

    ArrayBuffer类似 Java 中的ArrayList。它是数组缓冲。

    scala> import scala.collection.mutable.ArrayBuffer
    import scala.collection.mutable.ArrayBuffer
    
    scala> val arrayBuffer = new ArrayBuffer[Int]
    arrayBuffer: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()
    
    scala> arrayBuffer += 0
    res7: arrayBuffer.type = ArrayBuffer(0)
    
    scala> arrayBuffer += 1
    res8: arrayBuffer.type = ArrayBuffer(0, 1)
    
    scala> arrayBuffer += (2,3,4,5)
    res9: arrayBuffer.type = ArrayBuffer(0, 1, 2, 3, 4, 5)
    
    scala> arrayBuffer ++= Array(6,7,8,9,10) // 添加Array需要使用++
    res10: arrayBuffer.type = ArrayBuffer(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    
    scala> arrayBuffer.trimEnd(1) // 删除最后一个元素
    
    scala> println (arrayBuffer)
    ArrayBuffer(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
    

    ArrayBuffer 还支持在任意位置进行添加(insert)和删除(remove)操作

    scala> arrayBuffer.insert(2,100) // 在下标2处插入100
    
    scala> println (arrayBuffer)
    ArrayBuffer(0, 1, 100, 2, 3, 4, 5, 6, 7, 8, 9)
    
    scala> arrayBuffer.insert(5,101,102) // 在下标5处插入101,102
    
    scala> println (arrayBuffer)
    ArrayBuffer(0, 1, 100, 2, 3, 101, 102, 4, 5, 6, 7, 8, 9)
    

    反之,ArrayBuffer 的 remove 操作是同理。

    除此之外, ArrayBuffer 还有 sum、max、min、sorted 等常用函数。

    ArrayBuffer 到 Array 的转换: toArray

    scala> arrayBuffer.toArray
    res21: Array[Int] = Array(0, 1, 100, 2, 3, 101, 102, 4, 5, 6, 7, 8, 9)
    

    3.3 多维数组

    Scala 多维数组是通过数组的数组来实现的。二维数组看起来像是Array[Array[Int]]。要构造这样一个数组,可以用ofDim方法。

    二维数组的定义

    scala> val matrix=Array.ofDim[Int](3,4) 
    matrix: Array[Array[Int]] = Array(Array(0, 0, 0, 0), Array(0, 0, 0, 0), Array(0, 0, 0, 0))
    

    三维数组的定义

    scala> val matrix2 = Array.ofDim[Int](3,4,5)
    matrix2: Array[Array[Array[Int]]] = Array(Array(Array(0, 0, 0, 0, 0), Array(0, 0, 0, 0, 0), Array(0, 0, 0, 0, 0), Array(0, 0, 0, 0, 0)), Array(Array(0, 0, 0, 0, 0), Array(0, 0, 0, 0, 0), Array(0, 0, 0, 0, 0), Array(0, 0, 0, 0, 0)), Array(Array(0, 0, 0, 0, 0), Array(0, 0, 0, 0, 0), Array(0, 0, 0, 0, 0), Array(0, 0, 0, 0, 0)))
    

    所以,多维数组的定义:
    Array.ofDim[类型](维度1, 维度2, 维度3,....)

    4. 不可变Map 和 可变Map

    4.1 不可变Map

    不可变Map位于scala.collection.immutable包中。

    假设,我们定义某学生的期末考试分数,它是一个不可改变的Map集合。

    scala> val scores = Map("math"->90,"english"->85,"chinese"->80)
    scores: scala.collection.immutable.Map[String,Int] = Map(math -> 90, english -> 85, chinese -> 80)
    

    获取该学生的数学成绩

    scala> scores("math")
    res8: Int = 90
    

    获取该学生的计算机成绩,其实并没有录入计算机课程的分数会出现什么情况呢?

    scala> scores("computer")
    java.util.NoSuchElementException: key not found: computer
      at scala.collection.immutable.Map$Map3.apply(Map.scala:156)
      ... 30 elided
    

    不出意外地报了一个错误。
    所以,我们得先判断一下map里是否包含计算机课程,包含的话就取出成绩,不包含的话只能默认0分,这样代码才安全。

    scala> val computer = if (scores.contains("computer")) scores("computer") else 0
    computer: Int = 0
    

    这下,命令行就不会报错了。

    4.2 可变Map

    可变Map位于scala.collection.mutable包中。
    对于刚才的情况,添加该学生计算机的成绩。

    scala> scores +=("computer"->88)
    <console>:13: error: value += is not a member of scala.collection.immutable.Map[String,Int]
           scores +=("computer"->88)
    

    scala是会报错的,因为scores是不可变map。

    重新定义scores,让它变成可变的map,这样就可以添加其他课程的成绩了。

    scala> val scores = scala.collection.mutable.Map("math"->90,"english"->85,"chinese"->80)
    scores: scala.collection.mutable.Map[String,Int] = Map(chinese -> 80, math -> 90, english -> 85)
    
    scala> scores +=("computer"->88)
    res12: scores.type = Map(computer -> 88, chinese -> 80, math -> 90, english -> 85)
    

    换一个角度,我们来看看如何定义一个空的Map

    
    scala> val map=new scala.collection.mutable.HashMap[String,Int]()
    map: scala.collection.mutable.HashMap[String,Int] = Map()
    
    scala> map += ("computer"->88)
    res15: map.type = Map(computer -> 88)
    
    scala> map +=  ("math"->90,"english"->85,"chinese"->80)
    res16: map.type = Map(computer -> 88, chinese -> 80, math -> 90, english -> 85)
    
    scala> println (map)
    Map(computer -> 88, chinese -> 80, math -> 90, english -> 85)
    
    scala> map.getClass
    res18: Class[_ <: scala.collection.mutable.HashMap[String,Int]] = class scala.collection.mutable.HashMap
    

    未来,我会单独再整理一篇集合相关的文章。

    5. 元组

    元组(Tuple)是不同类型的值的聚集。

    定义一个元组:

    scala> val tuple = (0,false,"Scala")
    tuple: (Int, Boolean, String) = (0,false,Scala)
    

    然后我们可以用方法_1、_2、_3访问其元素。

    scala> println(tuple._1) // 打印第一个元素
    0
    
    scala> println(tuple._2) // 打印第二个元素
    false
    
    scala> println(tuple._3) // 打印第三个元素
    Scala
    

    值得注意的是,元组的索引是从1开始,而数组的索引是从0开始。

    通常,使用模式匹配来获取元组的元素。

    scala> val (first, second, third)=tuple
    first: Int = 0
    second: Boolean = false
    third: String = Scala
    

    如果并不是所有的元素都需要,那么可以在不需要的元素位置上使用占位符_:

    scala> val (first, second, _ ) = tuple
    first: Int = 0
    second: Boolean = false
    

    总结

    这篇笔记还是整理一些基础的知识。

    下一篇开始,我会整理 Scala 的类相关的内容。

    先前的文章:
    Scala学习笔记(二)
    Scala学习笔记(一)

    相关文章

      网友评论

      • 终生学习丶:sorry,原谅我的肤浅...百度了原来三元就是三目..且使用频率居然以三目为首!!..:fearful: 什么鬼
      • 终生学习丶:三目(童子)?不是说好的三元吗

      本文标题:Scala学习笔记(三)

      本文链接:https://www.haomeiwen.com/subject/trbdittx.html