zoukankan      html  css  js  c++  java
  • Scala入门学习笔记三--数组使用

    前言

    本篇主要讲Scala的Array、BufferArray、List,更多教程请参考:Scala教程

    本篇知识点概括

    • 若长度固定则使用Array,若长度可能有 变化则使用ArrayBuffer
    • 提供初始值时不要使用new,复杂对象数组没有提供初始值时必须提供new
    • 用()来访问元素
    • 用for(elem <- arr)来遍历数组
    • 用for(elem <- arr if...)...yield...来将原数组转型为新数组
    • Scala数组和Java数组可以互操作

    数组

    1、定长数组定义:

    //定义一个长度为10的数值数组
    scala> val numberArray = new Array[int](10)
    numberArray:Array[Int] = Array(0,0,0,0,0,0,0,0,0,0)
    //定义一个长度为10的String类数组
    scala> val strArray = new Array[String](10)
    strArray:Array[String] = Array(null, null, null, null, null, null, null, null, null, null)
    
    //由上可以看出,复杂对象类型在数组定义时被初始化为null,数值型呗初始化为0,并且上面复杂类型定义的时候必须加new,否则会报错
    
    //提供初始值的定义数组
    scala> val strArray2 = Array("First", "Second")  //这里说明已提供初始值就不需要new
    strArray2:Array[String] = Array(First, Second)
    
    scala> strArray2(0) = "Goodbye"
    strArray2:Array[String] = Array(Goodbye, Second)
    
    

    2、变长数组定义
    对于长度需要变化的数组,Java有ArrayList,C++有vector。Scala中的等效数据结构为ArrayBuffer

    //导入可变包,Scala中的可变集合都是放在mutable中,使用时要导入
    scala> import scala.collection.mutable.ArrayBuffer
    import scala.collection.mutable.ArrayBuffer
    
    scala> val arrayBuffer = ArrayBuffer[Int]()
    arrayBuffer: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()
    
    //在尾部添加一个值
    scala> arrayBuffer += 1
    res17: arrayBuffer.type = ArrayBuffer(1)
    
    //在尾部添加多个元素
    scala> arrayBuffer += (2, 3, 4, 5)
    res19: arrayBuffer.type = ArrayBuffer(1, 2, 3, 4, 5)
    
    //在尾部添加一个集合
    scala> arrayBuffer ++= Array(6, 7, 8, 9)
    res20: arrayBuffer.type = ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9)
    
    //移除最后2个元素
    scala> arrayBuffer.trimEnd(2)
    
    //在开头移除1一个元素
    scala> arrayBuffer.trimStart(2)
    
    scala> arrayBuffer
    res23: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(2, 3, 4, 5, 6, 7)
    
    
    //在任意位置插入或者删除元素
    scala> arrayBuffer.insert(2, 6)
    //ArrayBuffer(2, 3, 6, 4, 5, 6, 7)
    
    scala> arrayBuffer.insert(1, 2, 3, 4)
    //ArrayBuffer(2, 1, 2, 3, 4, 3, 6, 4, 5, 6, 7)
    
    scala> arrayBuffer.remove(2)
    //ArrayBuffer(2, 1, 3, 4, 3, 6, 4, 5, 6, 7)
    
    scala> arrayBuffer.remover(1, 8)
    //ArrayBuffer(2, 7)
    

    3、变长数组和定长数组转换

    //变长转换长定长
    scala > arrayBuffer.toArray
    //Array(2, 7)
    
    //定长转换成变长
    scala>res7.toBuffer
    //ArrayBuffer(2, 7)
    

    4、遍历定长和变长数组

    for(i <- 0 until.arrayBuffer.length)
        println(i + ": " + a(i))
    
    

    0 until.arrayBuffer.length实际上是一个方法调用,返回的是一个区间Range: 0.until(arrayBuffer.length)
    for(i <- 区间)会让变量i遍历该区间的所有值
    如果想要在区间中步长不为1,则:0 until (arrayBuffer.length, 2)
    如果想要数组从尾端开始,则遍历的写法为:(0 until (arrayBuffer.length, 2)).reverse

    Scala也提供了一个和Java增强for循环类似的for ``` //增强for for(i <- arrayBuffer) println(i + ": " + a(i)) ```

    5、数组转换
    《Scala入门学习笔记二-基本数据类型、程序控制结构》提到在for循环推导式,可以利用原来的数组产生一个新的数组。

    scala> val a = Array(2, 3, 5, 7, 11)
    a: Array[Int] = Array(2, 3, 5, 7, 11)
    //这里产生了一个新的数组,原来的数组也在
    scala> val result = for(elem <- a) yield 2 * elem
    result: Array[Int] = Array(4, 6, 10, 14, 22)
    
    

    如果for中使用的是定长数组,则for(...)...yield之后得到的是定长数组;如果使用的是变长数组,则会得到变长数组

    • Scala也提供了另外一种做法
    scala> a.filter(_ % 2 == 0).map(2 * _)
    
    甚至
    scala>a.filter(_ % 2 == 0).map{2 * _}
    

    例子:
    给定一个整数的缓冲数组,我们想要移除第一个负数之外的所有负数。有几种做法

    //第一种做法:
    var first = true
    var n = a.length
    var i = 0
    while(i < n){
        if(a(i) > 0) i += 1
        else{
            if(first) {first = false; i += 1}
            else {a.remove(i); n-= 1}
        }
    }
    
    //第二种做法:
    //首先使用一个新数组用于记录满足条件的数组的下标
    val first = true
    val indexes = for(i <- 0 until a.length if first || a(i) > 0) yield {
        if(a(i) < 0) first = false; i
    }
    //然后将元素移动到该去的位置,截断尾端
    for(j <- o until indexes.length) a(j) = a(indexes(j))
    a.trimEnd(a.length-indexes.length)
    

    6、常用算法
    Scala针对数组提供了一个常用的函数

    //定义一个整型数组
    scala> val intArr=Array(1,2,3,4,5,6,7,8,9,10)
    intArr: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    
    //求和
    scala> intArr.sum
    res87: Int = 55
    
    //求最大值
    scala> intArr.max
    res88: Int = 10
    
    scala> ArrayBuffer("Hello","Hell","Hey","Happy").max
    res90: String = Hey
    
    //求最小值
    scala> intArr.min
    res89: Int = 1
    
    //排序
    //sorted方法将数组或数组缓冲排序并返回经过排序的数组或数组缓冲,原始数组被保留
    scala>val b = ArrayBuffer(1, 7, 2, 9)
    b:ArrayBuffer[Int] = ArrayBuffer(1, 7, 2, 9)
    scala>val bSorted = b.sorted(_<_) 
    bSorted: ArrayBuffer[Int] = ArrayBuffer(1, 2, 7, 9)
    
    //toString()方法
    scala> intArr.toString()
    res94: String = [I@141aba8
    
    //mkString()方法
    scala> intArr.mkString(",")
    res96: String = 1,2,3,4,5,6,7,8,9,10
    
    scala> intArr.mkString("<",",",">")
    res97: String = <1,2,3,4,5,6,7,8,9,10>
    

    7、ArrayBuffer Scaladoc解析
    初学者在查看sacaladoc时常常会感到困惑,不用担心,随着学习的深入,api文档中的内容将逐渐清晰
    下面给出两个示例:
    ++=方法传入的参数类型是TraversableOnce Trait的子类,它返回的是更新好的ArrayBuffer

    ++=方法解析

    dropWhile传入的是一个函数,该函数返回值是布尔类型,dropWhile反回的是操作后的ArrayBuffer

    dropWith方法解析

    8、多维数组
    和Java一样,多维数组是通过数组的数组来实现的。

    //第一种构造方式
    val metrix = Array.ofDim[Double](3, 4) //3行 4列
    
    //访问其中的元素
    metrix(row)(column)  =42
    
    //可以创建不规则的数组,每一行的长度不相同
    val triangle = new Array[Array[Int]](10)
    for(i <- 0 until triangle.length)
        trianglr(i) = new Array[Int](i+1)
    
    //在创建的时候赋值
    scala> val metrix = Array(Array(1, 2, 3), Array(2.3, 3.4), Array("asdf", "asdfas"))
    metrix: Array[Array[_ >: String with Double with Int]] = Array(Array(1, 2, 3), Array(2.3, 3.4), Arra
    y(asdf, asdfas))
    
    //打印输出数组
    scala> for(i <- metrix) println(i.mkString(" "))
    1 2 3
    2.3 3.4
    asdf asdfas
    
    //输出二维数组的每个值
    scala> for(i <- metrix; from = i; j <- from) println(j)
    1
    2
    3
    2.3
    3.4
    asdf
    asdfas
    
  • 相关阅读:
    Select 多个表并且相关联转置
    Excel输入公式后只显示公式却不计算如何解决?
    Excel 下来公式 内容却一样
    MySQL数据迁移到SQL Server
    C# Excel 中设置文字对齐方式、方向和换行
    Response.write()弹出窗口的问题!
    ORA-12514 TNS 监听程序当前无法识别连接描述符中请求服务
    Hibernate中连接数据库的配置
    ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...
    帝国cms的tags页面url伪静态的设置
  • 原文地址:https://www.cnblogs.com/miqi1992/p/5614024.html
Copyright © 2011-2022 走看看