为了账号安全,请及时绑定邮箱和手机立即绑定

Scala(七)-①-数据结构-集合-Array和List和ListBuffer

标签:
大数据

Java中不可变集合

  • 不可变集合概念(java为例)

public class ImmutableDemo01ForJava {   public static void main(String[] args) {       // 1.不可变集合,内容可变,旦数组本身不能动态增长
       int []nums = new int[3];
       nums[2] = 2;       //  nums[3] = 1  错误

       // 2.可变集合,集合本省能够动态增长ArrayList arrayList = new ArrayList<String>();
       arrayList.add("t1");
       System.out.println(arrayList.hashCode());
       arrayList.add("t2");
       System.out.println(arrayList.hashCode());
   }
}

Scala中的集合

特点

  • Scala同时支持不可变集合可变集合,不可变集合可以安全的并发访问

两个主要的包:
不可变集合:scala.collection.immutable
可变集合: scala.collection.mutable

  • Scala默认采用不可变集合,对于几乎所有的集合类,Scala都同时提供了可变(mutable)和不可变(immutable)的版本

  • Scala的集合有三大类:序列Seq集Set映射Map,所有的集合都扩展自Iterable特质,在Scala中集合有可变(mutable)和不可变(immutable)两种类型.

举个例子

  • 不可变集合: scala不可变集合,就是这个集合本身不能动态变化.(类似java的数组,是不可以动态增长的)

  • 可变集合:可变集合,就是这个集合本身可以动态变化的.(比如:ArrayList,是可以动态增长的)

不可变集合继承层次一栏图

webp

image.png

可变集合继承层次一栏图

webp

image.png

细节

  • Seq是Java中没有的,List归属于Seq.所以这里的List和Java不一样.

  • for循环里的1 to 3,就是基于IndexSeq下的Vector

  • String也是属于indexSeq

  • Queue和Stack归属于LinearSeq.即是线性的,有头有尾

  • IndexSeqLinearSeq.IndexSeq是基于索引的序列,LinearSeq是线性序列

① 数组

Why

Scala同时支持不可变集合可变集合.不可变集合是线程安全的.

  • 队列的应用场景
    推荐系统要用户最近浏览的10个商品.

How

  • 学习集合的创建、修改、删除、增加

定长数组-Array

创-方式一-new Array
/**
  * @author sweetcs
  */object ArrayDemo01 {  def main(args: Array[String]): Unit = {    // 默认为零
    var arr = new Array[Int](4)
    println("数组长度=" + arr.length)
    println("循环遍历数组:")    for (item <- arr) {
      println(item)
    }

    arr(3)=1
    
    println("循环遍历数组:")    for (item <- arr) {
      println(item)
    }

  }
}
创-方式二-Array
/**
  * @author sweetcs
  */object ArrayDemo02ForApply {  def main(args: Array[String]): Unit = {    // 数组元素的类型时Any.一旦定义就不可在更改
    var array = Array(1, 2, "beijing")    // 数组元素的类型时Int.一旦定义就不可在更改
    var arrayOfInts = Array(1,2)    for (item <- array) {
      println(item)
    }    // 传统for循环基于索引遍历
    var len = array.length    for (i <- 0 until len) {
      printf("%s\t", array(i))
    }
  }
}

变长数组-ArrayBuffer

创-变长数组的增删改查
/**
  * @author sweetcs
  */object MutableArrayDemo01 {  def main(args: Array[String]): Unit = {    
    val arrayBuffer = ArrayBuffer[Any](2,3,"beijing")
    println(arrayBuffer(2))

    println(arrayBuffer.hashCode())    // 增
    arrayBuffer.append(5, 6)
    println(arrayBuffer.hashCode())    // 删
    arrayBuffer.remove(0)    // 查
    for (item <- arrayBuffer) {
      print(item + "\t")
    }
  }
}

定长数组和变长数组的转换

  • toArray

  • toBuffer

/**
  * @author sweetcs
  */object MutableArrayDemo02ForTranslateImutable {  def main(args: Array[String]): Unit = {    val arrayBuffer = ArrayBuffer(1,2,"beijing")    val array = arrayBuffer.toArray
    println(array.hashCode(), arrayBuffer.hashCode())
    println("遍历不可变数组")    for (item <- array) {
      println(item)
    }    val mutableArray = array.toBuffer
    mutableArray.append(3)
    println("遍历mutableArray")    for (item <- mutableArray) {
      println(item)
    }

    println("遍历arrayBuffer")    for (item <- arrayBuffer) {
      println(item)
    }
  }
}

多维数组

语法
// 创建一个3行四列的Double数组val arr = Array.ofDim[Double](3,4)
多维数组Demo
/**
  * @author sweetcs
  */object ArrayDemo05ForMultiplyDimArray {  def main(args: Array[String]): Unit = {    val arr = Array.ofDim[Int](3, 4)    // 查
    println("查case==========")    for (row <- arr) {
      println(row)      for (col <- row) {
        println(col + "\t")
      }
    }

    println("改case==========")    // 改
    arr(0)(1) = 3
    for (row <- arr) {
      println(row)      for (col <- row) {
        println(col + "\t")
      }
    }

  }
}

Java数组(List)和Scala数组(ArrayBuffer)的互转

  • Scala->Java

object ArrayDemo06ForScalaArrayToJavaArray {  def main(args: Array[String]): Unit = {    //创建了ArrayBuffer
    val arr = ArrayBuffer("1", "2", "3")    //下面的import 引入了我们需要的隐式函数【这里就是隐式函数的应用】
    //implicit def bufferAsJavaList[A](b : scala.collection.mutable.Buffer[A]) : java.util.List[A]
    import scala.collection.JavaConversions.bufferAsJavaList    // 触发隐式转换
    val javaArr = new ProcessBuilder(arr)    //返回的是 List<String>
    val arrList = javaArr.command()

    println(arrList) //输出 [1, 2, 3]
  }
}
  • Java->Scala

object ArrayDemo07ForJavaArrayToScalaArray {  def main(args: Array[String]): Unit = {    val arrList = new java.util.ArrayList[String]()    import scala.collection.JavaConversions.asScalaBuffer    import scala.collection.mutable    // java.util.List ==> Buffer
    val scalaArr: mutable.Buffer[String] = arrList
    scalaArr.append("jack")
    scalaArr.append("tom")
    println(scalaArr)
    scalaArr.remove(0)
    println(scalaArr) // (2,3,jack,tom)

  }
}

What

  • 不可变集合: 集合本身不能变化,类似于Java里的数组,不是动态增长

  • 可变集合: 集合本身能变化

  • toBuffer的底层实现
    又重新new了一个ArrayBuffer,将数据拷贝到这个ArrayBuffer实例中

  override def toBuffer[A1 >: A]: mutable.Buffer[A1] = {    val result = new mutable.ArrayBuffer[A1](size)
    copyToBuffer(result)
    result
  }

Details

  • Scala创建的集合几乎所有是不可变集合.

  • Scala集合集合的三大类型Seq\Set\Map

  • ArrayBuffer是变长数组,类似于ArrayList

  • 定长数组和变长数组的相互转换, 返回的是新数组,不改变旧数组


② 元组

Why

  • 元组用来解决那些想把不同的数据类型放在一起的需求.

  • 元组可以理解为一个容器, 可以存放各种相同或不同类型的数据.

How

元组语法

使用小括号标识元组.

val t = (1,23,"we are")
元组DEMO
  • 元组的创建元组类型

object TupleDemo01 {  def main(args: Array[String]): Unit = {    val tuple1 = (1,2,3,4,"hello")
    println(tuple1, tuple1.getClass) // ((1,2,3,4,hello),class scala.Tuple5)

  }
}
  • 元组访问,序号方式(1开始)、索引方式(0开始)

  • 元组遍历需要使用迭代器

object TupleDemo02ForAccess {  def main(args: Array[String]): Unit = {    val tuple = (1, 2, 3, "beijing")

    println(tuple._1)
    println(tuple.productElement(0))

    println("元组的遍历")    // 元组遍历,要用迭代器
    for (item <- tuple.productIterator) {
      println(item)
    }

  }
}

What

元组的访问-索引方式(0开始)原理
  @throws(classOf[IndexOutOfBoundsException])  override def productElement(n: Int) = n match { 
    case 0 => _1    case 1 => _2    case 2 => _3    case 3 => _4    case _ => throw new IndexOutOfBoundsException(n.toString())
 }

Details

  • 编译期根据Tuple的数据个数,创建对应元组类型.例如, Tuple5表示这个元组有5个元素.

  • 元组的元素个数最多是22个.


③ List

Why

List是Seq的子类,用于按序存放元素.

How

不可变List

  • list的创建和访问

 val list = List(1, 2, 3, "beijing")
  • list元素的追加方式,使用+:或者:+, 冒号一边为list,返回的是一个新List对象
    代码

/**
  * @author sweetcs
  */object ListDemo02ForAppendAndReturnNewList {  def main(args: Array[String]): Unit = {    val list = List(1, 2, 3, "beijing")    // 在列表的最后追加
    val newList = list :+ 6

    // 在列表的头追加
    val newList02 = 6 +: list
    println(s"list hashcode = ${list.hashCode()}, newList = ${newList.hashCode()}, newList02 = ${newList02.hashCode()}")
    println("newList= " + newList)
    println("newList02= " + newList02)
  }
}

输出

list hashcode = -1049219423, newList = 173175143, newList02 = -1337286218
newList= List(1, 2, 3, beijing, 6)
newList02= List(6, 1, 2, 3, beijing)
  • ::和:::添加集合

object ListDemo02ForAppendAndReturnNewList {  def main(args: Array[String]): Unit = {    val list = List(1, 2, 3, "beijing")    // 在列表的最后追加
    val newList = list :+ 6

    // 使用::添加元素, 会将一个集合当成一个整体放入集合中.
    // 使用:::添加元素, 会将一个集合中的元素都依次添加进去
    val newList03 = 4 :: 5 :: 6 :: 7 :: list :: Nil
    println(newList03)    val newList04 = 4 :: 5 :: 6 :: 7 :: list ::: Nil
    println(newList04)
  }
}

可变list-ListBuffer

ListBuffer是可变的list集合, 可以添加, 删除元素,ListBuffer属于序列

object ListDemo03ForListBuffer {  def main(args: Array[String]): Unit = {    val lst0 = ListBuffer[Int](1, 2, 3)    //如何访问
    println("lst0(2)=" + lst0(2)) // 输出 lst0(2)= 3
    for (item <- lst0) { // 遍历,是有序
      println("item=" + item)
    }    //动态的增加元素,lst1就会变化, 增加一个一个的元素
    val lst1 = new ListBuffer[Int] //空的ListBuffer
    lst1 += 4 // lst1 (4)
    lst1.append(5) // list1(4,5)

    //
    lst0 ++= lst1 // lst0 (1, 2, 3,4,5)

    println("lst0=" + lst0)    val lst2 = lst0 ++ lst1 // lst2(1, 2, 3,4,5,4,5)
    println("lst0=" + lst0)
    println("lst2=" + lst2)    val lst3 = lst0 :+ 5 // lst0 不变 lst3(1, 2, 3,4,5,5)
    println("lst3=" + lst3)


    println("=====删除=======")
    println("lst1=" + lst1)
    lst1.remove(1) // 表示将下标为1的元素删除
    for (item <- lst1) {
      println("item=" + item) //4
    }

  }
}

Details

  • Scala中的List是能存放元素,Java中的List是一个接口

  • List属于Seq,默认情况下创建的List是不可变List实例

  • List在scala包对象声明的,因此不需要引入其它包也可以使用val List = scala.collection.immutable.List

  • :: 运算时,集合对象一定要放置在最右边.

  • ::: 运算符是将集合中的每一个元素加入到集合中去,并且左右两边都必须是集合.



作者:sixleaves
链接:https://www.jianshu.com/p/bdf90fc486ed


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消