Scala集合,Scala序列,Scala Seq,Array,ArrayBuffer,元组Tuple,列表,List,ListBuffer,队列QueueScala数组与JavaList的互转

1、Scala集合基本介绍

1.1  有关Scala集合的几个重点

  1. Scala同时支持不可变集合和可变集合,可变集合可以安全的并发访问。

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

  3. Scala默认采用不可变集合,对于几乎所有的集合类,Scala都同时提供了可变和不可变的版本。

  4. Scala集合有三大类:序列Seq、集Set、映射Map,所有的集合都扩展自Iterable特质。

1.2 可变集合和不可变集合

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

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

1.3 不可变集合继承结构

Scala集合,Scala序列,Scala Seq,Array,ArrayBuffer,元组Tuple,列表,List,ListBuffer,队列QueueScala数组与JavaList的互转_第1张图片

 

1.4不可变集合的小结

  1. Set、Map是Java中也有的集合

  2. Seq是Java没有的,我们发现List归属到Seq了,因此这里的List就和java不是同 一个概念了

  3. 我们前面的 for 循环有一个 1 to 3 ,就是 IndexedSeq 下的 Vector 

  4. String 也是属于 IndexeSeq

  5. 大家注意 Scala 中的 Map 体系有一个 SortedMap,说明 Scala 的 Map 可以支持 排序

  6. 我们发现经典的数据结构比如 Queue 和 Stack 被归属到 LinearSeq

  7. IndexSeq 和 LinearSeq 的区别[IndexSeq 是通过索引来查找和定位,因此速度快,比如 String 就 是一个索引集合,通过索引即可定位] [LineaSeq 是线型的,即有头尾的概念,这种数据结构一般是通 过遍历来查找,它的价值在于应用到一些具体的应用场景 (电商网站, 大数据推荐系统 :最近浏览的 10 个商品)

1.5 可变集合的继承结构

Scala集合,Scala序列,Scala Seq,Array,ArrayBuffer,元组Tuple,列表,List,ListBuffer,队列QueueScala数组与JavaList的互转_第2张图片

1.6 对可变集合的说明

  1. 在可变集合中比不可变集合更加丰富。

  2. 在Seq集合中,增加了buffer类型,将来开发中常用的有ArrayBuffer和ListBuffer。

  3. 如果涉及到线程安全,可以选择使用syn开头的集合。

  4. 其他说明可以参考不可变集合。

2、数组

    这里的数组等同于Java中的数组,中括号的类型就是数组的范型。

2.1 定长数组

2.1.1 第一种方式定义数组   

//1. 创建了一个 Array 对象,

//2. [Int] 表示泛型,即该数组中,只能存放 Int 

//3. [Any] 表示 该数组可以存放任意类型

//4. 在没有赋值情况下,各个元素的值 0

//5. arr01(3) = 10 表示修改 第 4 个元素的值

val arr1 = new Array[Int](10) //

arr1.length

println("arr01(0)=" + arr01(0)) // 0 

//数据的遍历

for (i <- arr01) { 

    println(i)

println("--------------------“) 

arr01(3) = 10 //

for (i <- arr01) {

    println(i) 

}

2.1.2 第二种定义数组

package com.atguigu.chapter10

object ArrayDemo02 {

    def main(args: Array[String]): Unit = {

        //说明

        //1. 使用的是 object Array 的 apply

        //2. 直接初始化数组,这时因为你给了 整数和 "", 这个数组的泛型就 Any 

        //3. 遍历方式一样

        var arr02 = Array(1, 3, "xx")

        arr02(1) = "xx"

        for (i <- arr02) {

            println(i) 

        }

        //可以使用我们传统的方式遍历,使用下标的方式遍历 

        for (index <- 0 until arr02.length) {

            printf("arr02[%d]=%s", index , arr02(index) + "\t”) 

        }

    } 

}

 

2.2 变长数组

2.2.1 基本使用

package com.atguigu.chapter10

import scala.collection.mutable.ArrayBuffer

object ArrayBufferDemo01 {

    def main(args: Array[String]): Unit = {

        //创建 ArrayBuffer

        val arr01 = ArrayBuffer[Any](3, 2, 5)

        //访问,查询

        //通过下标访问元素

        println("arr01(1)=" + arr01(1)) // 

        arr01(1) = 2 

        //遍历

        for (i <- arr01) {

            println(i) 

        }

        println(arr01.length) //3 

        println("arr01.hash=" + arr01.hashCode())

        //修改 [修改值,动态增加]

        //使用 append 追加数据 ,append 支持可变参数 

        //可以理解成 java 的数组的扩容 

        arr01.append(90.0,13) // (3,2,5,90.0,13) 

        println("arr01.hash=" + arr01.hashCode())

        println("===================")

        arr01(1) = 89     //修改 (3,89,5,90.0,13) 

        println("--------------------------")

        for (i <- arr01) {

            println(i) 

        }

        //删除… 

        //删除,是根据下标来说

        arr01.remove(0) // (89,5,90.0,13) 

        println("--------删除后的元素遍历---------------“) 

        for (i <- arr01) {

            println(i) 

        }

        println("最新的长度=" + arr01.length) // 4

    } 

}

 

2.2.2 变长数组小结

  1. ArrayBuffer是变长数组,类似Java中的ArrayList

  2. val arr2 = ArrayBuffer[Int]() 也是使用的 apply 方法构建对象

  3. def append(elems: A*) { appendAll(elems) } 接收的是可变参数.

  4. 每 append 一次,arr 在底层会重新分配空间,进行扩容,arr2 的内存地址会发生变化,也就成 为新的 ArrayBuffer

 

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

    在开发中可能会遇到定长和变长之间的转换问题

 

2.3.1 转换方法

arr1.toBuffer //定长数组转可变数组

arr2.toArray //可变数组转定长数组

 

2.3.2 注意事项

arr2.toArray 返回结果才是一个定长数组, arr2 本身没有变化

arr1.toBuffer 返回结果才是一个可变数组, arr1 本身没有变化

 

2.3.3 实例

package com.atguigu.chapter10

import scala.collection.mutable.ArrayBuffer

object Array22ArrayBuffer {

    def main(args: Array[String]): Unit = {

        val arr2 = ArrayBuffer[Int]() 

        // 追加值

        arr2.append(1, 2, 3) 

        println(arr2)

        //说明

        //1. arr2.toArray 调用 arr2 的方法 toArray 

        //2. 将 ArrayBuffer ---> Array

        //3. arr2 本身没有任何变化

        val newArr = arr2.toArray

        println(newArr)

        //说明

        //1. newArr.toBuffer 是把 Array->ArrayBuffer 

        //2. 底层的实现

        /*

        override def toBuffer[A1 >: A]: mutable.Buffer[A1] = { 

            val result = new mutable.ArrayBuffer[A1](size) copyToBuffer(result)    

            result

        }

        */

        //3. newArr 本身没变化

        val newArr2 = newArr.toBuffer 

        newArr2.append(123)

        println(newArr2) 

        //案例演示+说明

    }

}

 

2.4 多维数组的定义和说明

2.4.1 多维数组的定义

//定义

val arr = Array.ofDim[Double](3,4) 

//说明:二维数组中有三个一维数组, 每个一维数组中有四个元素

//赋值

arr(1)(1) = 11.11

 

2.4.2 多维数组的使用

package com.atguigu.chapter10

object MultiplyArray {

    def main(args: Array[String]): Unit = {

        //创建

        val arr = Array.ofDim[Int](3, 4)

        //遍历

        for (item <- arr) { //取出二维数组的各个元素(一维数组) 

            for (item2 <- item) { // 元素(一维数组) 遍历

                print(item2 + "\t”) 

            }

            println() 

        }

        //指定取出 

        println(arr(1)(1)) // 0

        //修改值 

        arr(1)(1) = 100

        //遍历

        println("=====================")

        for (item <- arr) { //取出二维数组的各个元素(一维数组)

            for (item2 <- item) { // 元素(一维数组) 遍历 

                print(item2 + "\t")

            }

            println() 

        }

        //使用传统的下标的方式来进行遍历 

        println("===================“) 

        for (i <- 0 to arr.length - 1) { //先对

            for (j <- 0 to arr(i).length - 1) { 

                printf("arr[%d][%d]=%d\t", i, j, arr(i)(j))

            }

            println() 

        }

    } 

}

 

2.5 Scala数组与JavaList的互转

2.5.1 互转代码

package com.atguigu.chapter10

import scala.collection.mutable.ArrayBuffer

object ArrayBuffer2JavaList {

    def main(args: Array[String]): Unit = {

        // Scala 集合和 Java 集合互相转换

        val arr = ArrayBuffer("1", "2", "3")

        /*

        implicit def bufferAsJavaList[A](b : scala.collection.mutable.Buffer[A]) : java.util.List[A] = { /*

compiled code */ } 

        */

        import scala.collection.JavaConversions.bufferAsJavaList

        //对象 ProcessBuilder , 因为 这里使用到上面的 bufferAsJavaList

        val javaArr = new ProcessBuilder(arr) //为什么可以这样使用? 

        // 这里 arrList 就是 java 中的 List

        val arrList = javaArr.command()

        println(arrList) //输出 [1, 2, 3] }

}

 

2.5.2 使用trait来实现参数的多态

trait MyTrait01 {}

class A extends MyTrait01 {} 

object B {

    def test(m: MyTrait01): Unit = { 

        println("b ok..")

    } 

}

//明确一个知识点

//当一个类继承了一个 trait 

//那么该类的实例,就可以传递给这个 trait 引用 val a01 = new A

B.test(a01)

 

2.6 Java的List转成Scala的数组

//java 的 List 转成 scala 的 ArrayBuffer 

//说明

//1. asScalaBuffer 是一个隐式函数

/*

implicit def asScalaBuffer[A](l : java.util.List[A]) : scala.collection.mutable.Buffer[A] = { /* compiled

code */ } 

*/

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”) 

scalaArr.remove(0) 

println(scalaArr) // (2,3,jack,tom)

 

 

3、元组

3.1元组基础

3.1.1元组的基本介绍

    元组可以理解为一个容器,可以存放各种相同或者不相同类型的数据。说的简单点,就是将多个无关的数据封装为一个整体,称为元组。最大的特点就是灵活,对数据没有过多的约束。

注意:元组中最大智能存放22个元素。

 

3.1.2 元组的创建

//创建

//说明 1. tuple1 就是一个 Tuple 类型是 Tuple5

//简单说明: 为了高效的操作元组 , 编译器根据元素的个数不同,对应不同的元组类型 

// 分别 Tuple1----Tuple22

val tuple1 = (1, 2, 3, "hello", 4) 

println(tuple1)

 

3.1.3 对创建代码的说明

  1. t1的类型是Tuple5类 是Scala特有的类型。

  2. t1的类型取决于t1后面有多少个元素,有对应关系。

  3. 最多只有22个元素。

 

3.2 元组的基本访问

3.2.1 基本介绍

    访问元组中的数据,可以采用顺序号(_顺序号),也可以通过索引访问。

 

3.2.2 应用实例

println("==================访问元组=========================") //访问元组

val t1 = (1, "a", "b", true, 2)

println(t1._1) // 1 //访问元组的第一个元素 ,从 1 开始

/*

override def productElement(n: Int) = n match {

case 0 => _1

case 1 => _2

case 2 => _3

case 3 => _4

case 4 => _5

case _ => throw new IndexOutOfBoundsException(n.toString())

*/

println(t1.productElement(0)) // 0 // 访问元组的第一个元素,从 0 开始

 

3.3 元组数据的遍历

Tuple 是一个整体,遍历需要调其迭代器

println("==================遍历元组=========================“) 

//遍历元组, 元组的遍历需要使用到迭代器

for (item <- t1.productIterator)

 

4、列表

4.1 列表的基本使用

4.1.1 基本介绍

Scala中的List和Java 中List不一样,Java中的List是一个接口,真正存放数据ArrayList,而Scala的List可以直接存放数据,就是一个object,默认情况下Scala的List是不可变的,List属于序列Seq。

val List = scala.collection.immutable.List 

object List extends SeqFactory[List]

 

4.1.2 创建List的应用案例

object ListDemo01 {

    def main(args: Array[String]): Unit = {

        //说明

        //1. 在默认情况下 List 是 scala.collection.immutable.List,即不可变

        //2. 在 scala 中,List 就是不可变的,如需要使用可变的 List,则使用 ListBuffer 

        //3. List 在 package object scala 做了 val List = scala.collection.immutable.List 

        //4. val Nil = scala.collection.immutable.Nil // List()

        val list01 = List(1, 2, 3) //创建时,直接分配元素 println(list01)

        val list02 = Nil //空集合

        println(list02)

    }

}

 

4.1.3 创建List案例的说明

  1. List默认情况下是不可变集合。

  2. List是在Scala包对象声明的,因此不需要引入其他包也可以使用。

  3. List可以存放任何类型的数据。

  4. 如果希望得到一个空列表,可以使用Nil对象,在Scala包对象声明的,因此不需要引入包也可以使用。

 

4.2 访问List

//访问 List 的元素

val value1 = list01(1) // 1 是索引,表示取出第 2 个元素. 

println("value1=" + value1) // 2

 

4.3 List元素的追加

4.3.1 基本介绍

向列表中增加元素,会返回新的列表/集合。注意:Scala中List元素的追加方式非常独特,和Java不一样。

 

4.3.2 案例

println("-------------list 追加元素后的效果-----------------")

//通过 :+ 和 +: 给 list 追加元素(本身的集合并没有变化)

var list1 = List(1, 2, 3, "abc")

// :+运算符表示在列表的最后增加数据

val list2 = list1 :+ 4 // (1,2,3,"abc", 4)

println(list1) //list1 没有变化 (1, 2, 3, "abc"),说明 list1 还是不可变 

println(list2) //新的列表结果是 [1, 2, 3, "abc", 4]

val list3 = 10 +: list1 // (10,1, 2, 3, "abc”) 

println("list3=" + list3)

 

4.3.3 在列表的最后增加数据

//:: 符号的使用

val list4 = List(1, 2, 3, "abc")

//说明 val list5=4::5::6::list4::Nil 步骤 

//1. List()

//2. List(List(1, 2, 3, "abc"))

//3. List(6,List(1, 2, 3, "abc"))

//4. List(5,6,List(1, 2, 3, "abc"))

//5. List(4,5,6,List(1, 2, 3, "abc"))

val list5 = 4 :: 5 :: 6 :: list4 :: Nil 

println("list5=" + list5)

//说明 val list6=4::5::6::list4:::Nil 步骤 

//1. List()

//2. List(1, 2, 3, "abc")

//3. List(6,1, 2, 3, "abc")

//4. List(5,6,1, 2, 3, "abc")

//5. List(4,5,6,1, 2, 3, "abc")

val list6 = 4 :: 5 :: 6 :: list4 ::: Nil 

println("list6=" + list6)

 

4.3.4 说明

  1. 符号::表示向集合中,新建集合添加元素。

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

  3. 运算规则,从右向左。

  4. :::运算符是将集合中每一个元素添加到集合中去

 

 

4.4 ListBuffer

4.4.1 基本介绍

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

 

4.4.2 案例

package com.atguigu.chapter10

import scala.collection.mutable.ListBuffer

object ListBufferDemo01 {

    def main(args: Array[String]): Unit = {

        //创建 ListBuffer

        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("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 

        }

    } 

}

 

5、队列-Queue

5.1 队列的基本介绍

5.1.1 队列的应用场景

因为队列结构我在学习数据结构课程的时候学的非常熟练了,所以不做过多的笔记,需要的小伙伴自己去找队列的资料和练习题。

5.1.2 队列的说明

  1. 队列是一个有序列表,在底层可以用数组或者链表来实现。

  2. 其输入和输出要遵循先入先出的原则。

  3. 在Scala中由设计者直接给我们提供队列类型使用。

  4. 在Scala中,有scala.collection.mutable.Queue和scala.collection.immutable.Queue,一般来说,我们在开发中通常使用可变集合中的队列。

 

5.2 队列的使用

5.2.1 队列的创建

//创建队列

val q1 =new mutable.Queue[int]

println(q1)

 

5.2.2 向队列中追加数据

//给队列增加元素 

q1 += 9 // (9)

println("q1=" + q1) // (9)

q1 ++= List(4,5,7) // 默认值直接加在队列后面 

println("q1=" + q1) //(9,4,5,7)

 

//q1 += List(10,0) // 表示将 List(10,0) 作为一个元素加入到队列中,

 

5.2.3 删除和加入队列元素

    在队列中,严格的遵守,入队列的数据,放在队尾,取的数据是从队列的头部取出来的。

//dequeue 从队列的头部取出元素 q1会变减少一个元素

val queueElement = q1.dequeue() 

println("queueElement=" + queueElement + "q1="+q1)

//enQueue 入队列,默认是从队列的尾部加入. 

q1.enqueue(100,10,100,888)

println("q1=" + q1) // Queue(4, 5, 7, 100,10,100,888)

 

5.2.4返回队列的元素

println("============Queue-返回队列的元素=================“) 

//队列 Queue-返回队列的元素

//1. 获取队列的第一个元素

println(q1.head) // 4, 对 q1 没有任何影响

//2. 获取队列的最后一个元素

println(q1.last) // 888, 对 q1 没有任何影响

//3. 取出队尾的数据 ,即:返回除了第一个以外剩余的元素,可以级联使用 

println(q1.tail) // (5, 7, 100,10,100,888)

println(q1.tail.tail.tail.tail) // (10,100,888)

 

5.2.5 判断队列是否为空

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(Scala,spark)