前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >大数据技术之_16_Scala学习_07_数据结构(上)-集合

大数据技术之_16_Scala学习_07_数据结构(上)-集合

作者头像
黑泽君
发布2019-04-09 16:31:33
1.2K0
发布2019-04-09 16:31:33
举报
文章被收录于专栏:黑泽君的专栏黑泽君的专栏

第十章 数据结构(上)-集合

10.1 数据结构特点

10.1.1 Scala 集合基本介绍
10.1.2 可变集合和不可变集合举例

示例代码如下:

代码语言:javascript
复制
package com.atguigu.chapter10.test;

import java.util.ArrayList;

public class JavaCollectionDemo {
    public static void main(String[] args) {
        // 不可变集合类似 java 的数组
        int[] nums = new int[3];
        nums[2] = 11;
        // nums[3] = 90; // 数组越界

        String[] names = {"bj", "sh"};
        System.out.println(nums + " " + names); // [I@12a3a380 [Ljava.lang.String;@29453f44

        // 可变集合举例
        ArrayList al = new ArrayList<String>();
        al.add("zs");
        al.add("zs2");
        System.out.println(al + " " + al.hashCode()); // [zs, zs2] 242625
        al.add("zs3");
        System.out.println(al + " " + al.hashCode()); // [zs, zs2, zs3] 7642233

    }
}

输出结果如下:

代码语言:javascript
复制
[I@12a3a380 [Ljava.lang.String;@29453f44
[zs, zs2] 242625
[zs, zs2, zs3] 7642233

10.2 Scala 不可变集合继承层次一览图

10.2.1 图
10.2.2 小结

  1、Set、Map 是 Java 中也有的集合。   2、Seq 是 Java 中没有的,我们发现 List 归属到 Seq 了,因此这里的 List 就和 java 不是同一个概念了。   3、我们前面的 for 循环有一个 1 to 3,就是 IndexedSeq 下的 Vector。   4、String 也是属于 IndexeSeq。   5、我们发现经典的数据结构,比如 Queue 和 Stack 被归属到 LinearSeq。   6、大家注意 Scala 中的 Map 体系有一个 SortedMap,说明 Scala 的 Map 可以支持排序。   7、IndexSeq 和 LinearSeq 的区别     IndexSeq 是通过索引来查找和定位,因此速度快,比如 String 就是一个索引集合,通过索引即可定位。     LineaSeq 是线型的,即有头尾的概念,这种数据结构一般是通过遍历来查找,它的价值在于应用到一些具体的应用场景(比如:电商网站,大数据推荐系统:最近浏览的10个商品)。

10.3 Scala 可变集合继承层次一览图

10.3.1 图
10.3.2 小结

  1、Scala 可变集合中比不可变集合丰富。   2、在 Seq 集合中,增加了 Buffer 集合,将来开发中,我们常用的有 ArrayBuffer 和 ListBuffer。   3、如果涉及到线程安全可以选择 Syn.. 开头的集合。   4、其他的小结参考不可变集合。

10.4 数组-定长数组(声明泛型)

10.4.1 第一种方式定义数组

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

代码语言:javascript
复制
val arr1 = new Array[Int](10)
// 赋值,集合元素采用小括号访问
arr1(1) = 7

示例代码如下:

代码语言:javascript
复制
package com.atguigu.chapter10.array

/**
  * 第一种方式定义数组
  * 说明:这里的数组等同于 Java 中的数组,中括号的类型就是数组的类型。
  */
object ArrayDemo01 {
  def main(args: Array[String]): Unit = {
    // 明
    // 1. 创建了一个 Array 对象
    // 2. [Int] 表示泛型,即该数组中,只能存放 Int
    // 3. [Any] 表示该数组可以存放任意类型
    // 4. 在没有赋值情况下,各个元素的值玩为0
    // 5. arr01(3) = 10 表示修改第4个元素的值
    val arr01 = new Array[Int](4) // 底层 int[] arr01 = new int[4]
    println(arr01.length) // 4
    println("arr01(0)=" + arr01(0)) // 0

    //数据的遍历
    for (i <- arr01) {
      println(i)
    }
    println("----------")

    arr01(3) = 10
    for (i <- arr01) {
      println(i)
    }

  }
}

输出结果如下:

代码语言:javascript
复制
4
arr01(0)=0
0
0
0
0
----------
0
0
0
10
10.4.2 第二种方式定义数组

说明:在定义数组时,直接赋值。

代码语言:javascript
复制
// 使用 apply 方法创建数组对象
val arr1 = Array(1, 2)

示例代码如下:

代码语言:javascript
复制
package com.atguigu.chapter10.array

/**
  * 第二种方式定义数组
  * 说明:在定义数组时,直接赋值。
  */
object ArrayDemo02 {
  def main(args: Array[String]): Unit = {
    // 说明
    // 1. 使用的是 object Array 的 apply 方法
    // 2. 直接初始化数组,因为你给了整数和字符串, 这个数组的泛型就是 Any 了
    // 3. 遍历方式一样
    var arr02 = Array(1, 3, "xxx")
    arr02(1) = "xx"
    for (i <- arr02) {
      println(i)
    }

    // 可以使用我们传统的方式遍历,使用下标的方式遍历
    for (index <- 0 until arr02.length) {
      printf("arr02[%d]=%s", index, arr02(index) + "\t")
    }

  }
}

输出结果如下:

代码语言:javascript
复制
1
xx
xxx
arr02[0]=1    arr02[1]=xx arr02[2]=xxx

10.5 数组-变长数组(声明泛型)

说明:

代码语言:javascript
复制
// 定义/声明
val arr2 = ArrayBuffer[Int]()
// 追加值/元素
arr2.append(7)
// 重新赋值
arr2(0) = 7

示例代码如下:

代码语言:javascript
复制
package com.atguigu.chapter10.array

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()) // arr01.hash=110266112


    // 修改 [修改值,动态增加]
    // 使用 append 追加数据,append 支持可变参数
    // 可以理解成 java 的数组的扩容
    arr01.append(90.0, 13) // (3, 2, 5, 90.0, 13)  append 底层重新 new 出一个数组,然后底层把新的地址值重新赋给 arr01
    println("arr01.hash=" + arr01.hashCode()) // arr01.hash=-70025354

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

    arr01(1) = 89 // 修改 (3, 89, 5, 90.0, 13)
    println("----------")
    for (i <- arr01) {
      println(i)
    }

    // 删除
    // 删除,是根据下标来说
    arr01.remove(0) // (89, 5, 90.0, 13) // arr01.hash=-1775231646
    println("arr01.hash=" + arr01.hashCode())
    println("----------删除后的元素遍历----------")
    for (i <- arr01) {
      println(i)
    }
    println("最新的长度=" + arr01.length) // 4

  }
}

输出结果如下:

代码语言:javascript
复制
arr01(1)=2
3
2
5
3
arr01.hash=110266112
arr01.hash=-70025354
====================
----------
3
89
5
90.0
13
arr01.hash=-1775231646
----------删除后的元素遍历----------
89
5
90.0
13
最新的长度=4
10.5.1 变长数组分析小结
10.5.2 定长数组与变长数组的转换

示例代码如下:

代码语言:javascript
复制
package com.atguigu.chapter10.array

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

输出结果如下:

代码语言:javascript
复制
ArrayBuffer(1, 2, 3)
[I@7a79be86
newArr2.hash=387518613
newArr2.hash=-1552340494
ArrayBuffer(1, 2, 3, 123)
10.5.3 多维数组的定义和使用

说明

代码语言:javascript
复制
// 定义
val arr = Array.ofDim[Double](3, 4)
// 说明:二维数组中有三个一维数组,每个一维数组中有四个元素

// 赋值
arr(1)(1) = 11.11

示例代码如下:

代码语言:javascript
复制
package com.atguigu.chapter10.array

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) = 10

    //遍历
    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()
    }

  }
}

输出结果如下:

代码语言:javascript
复制
0    0   0   0   
0    0   0   0   
0    0   0   0   
0
====================
0    0   0   0   
0    10  0   0   
0    0   0   0   
====================
arr[0][0]=0    arr[0][1]=0 arr[0][2]=0 arr[0][3]=0 
arr[1][0]=0    arr[1][1]=10    arr[1][2]=0 arr[1][3]=0 
arr[2][0]=0    arr[2][1]=0 arr[2][2]=0 arr[2][3]=0 

10.6 数组-Scala 数组与 Java 的 List 的互转

10.6.1 Scala 数组转 Java 的 List

在项目开发中,有时我们需要将 Scala 数组转成 Java 数组,看下面案例: 示例代码如下:

代码语言:javascript
复制
package com.atguigu.chapter10.array

import scala.collection.mutable.ArrayBuffer

object ArrayBuffer2JavaList {
  def main(args: Array[String]): Unit = {
    // Scala 集合和 Java 集合互相转换

    val scalaArr1 = 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(scalaArr1) // 为什么可以这样使用?使用了隐式转换,将 Scala 的 ArrayBuffer 转为 Java 的 List
    // 这里 arrList 就是 java 中的 List 了
    val arrList = javaArr.command()

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

输出结果如下:

代码语言:javascript
复制
[1, 2, 3]
10.6.2 Java 的 List 转 Scala 数组(mutable.Buffer)

示例代码如下:

代码语言:javascript
复制
package com.atguigu.chapter10.array

import scala.collection.mutable.ArrayBuffer

object ArrayBuffer2JavaList {
  def main(args: Array[String]): Unit = {
    // Scala 集合和 Java 集合互相转换

    val scalaArr1 = 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(scalaArr1) // 为什么可以这样使用?使用了隐式转换,将 Scala 的 ArrayBuffer 转为 Java 的 List
    // 这里 arrList 就是 java 中的 List 了
    val arrList = javaArr.command()

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

    // 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 scalaArr2: mutable.Buffer[String] = arrList

    scalaArr2.append("jack")
    scalaArr2.append("tom")
    scalaArr2.remove(0)
    println(scalaArr2) // ArrayBuffer(2, 3, jack, tom)
  }
}

输出结果如下:

代码语言:javascript
复制
[1, 2, 3]
ArrayBuffer(2, 3, jack, tom)
10.6.3 补充一个多态的知识点(使用 trait 来实现参数多态)

示例代码如下:

代码语言:javascript
复制
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)

10.7 元组 Tuple

10.7.1 元祖的基本介绍+元祖的创建

示例代码如下:

代码语言:javascript
复制
package com.atguigu.chapter10.tuple

object TupleDemo01 {
  def main(args: Array[String]): Unit = {
    // 创建
    // 说明 1. tuple1 就是一个 Tuple,类型是 Tuple5
    // 简单说明: 为了高效的操作元组,编译器根据元素的个数不同,对应不同的元组类型
    // 分别:Tuple1 --- Tuple22

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

输出结果如下:

代码语言:javascript
复制
(1,2,3,hello,4)
10.7.2 元组的创建-代码小结
10.7.3 元组数据的访问+遍历

Tuple 是一个整体,遍历需要调其迭代器。 示例代码如下:

代码语言:javascript
复制
package com.atguigu.chapter10.tuple

object TupleDemo01 {
  def main(args: Array[String]): Unit = {
    // 创建
    // 说明 1. tuple1 就是一个 Tuple,类型是 Tuple5
    // 简单说明: 为了高效的操作元组,编译器根据元素的个数不同,对应不同的元组类型
    // 分别:Tuple1 --- Tuple22

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

    println("====================访问元组====================")
    // 访问元组
    val t1 = (1, "a", "b", true, 2)
    println(t1._1) // 1 访问元组的第一个元素,从1开始
    println(t1.productElement(0)) // 0 访问元组的第一个元素,从0开始
    /* productElement 方法底层源码:只是使用到了模式匹配,本质是一样
    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("====================遍历元组====================")
    // 遍历元组,元组的遍历需要使用到迭代器
    for (item <- t1.productIterator) {
      println("item=" + item)
    }

  }
}

输出结果如下:

代码语言:javascript
复制
(1,2,3,hello,4)
====================访问元组====================
1
1
====================遍历元组====================
item=1
item=a
item=b
item=true
item=2

10.8 列表 List

10.8.1 创建 List + List 元素的访问

示例代码如下:

代码语言:javascript
复制
package com.atguigu.chapter10.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, "Hello") // 创建时,直接分配元素
    println(list01) // List(1, 2, 3, Hello)

    val list02 = Nil  // 空集合
    println(list02)   // List()

    // 访问 List 的元素
    val value1 = list01(1) // 1是索引,表示取出第2个元素
    println("value1=" + value1) // 2
    }
}

输出结果如下:

代码语言:javascript
复制
List(1, 2, 3, Hello)
List()
value1=2
10.8.2 创建 List 的应用案例小结
10.8.3 List 元素的追加

方式1-在列表的最后增加数据 方式2-在列表的最前面增加数据

方式3-在列表的最后增加数据

示例代码如下:

代码语言:javascript
复制
package com.atguigu.chapter10.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, "Hello") // 创建时,直接分配元素
    println(list01) // List(1, 2, 3, Hello)

    val list02 = Nil  // 空集合
    println(list02)   // List()

    // 访问 List 的元素
    val value1 = list01(1) // 1是索引,表示取出第2个元素
    println("value1=" + value1) // 2


    println("====================list追加元素后的效果====================")
    // 通过 :+ 和 +: 给 list 追加元素(本身的集合并没有变化
    // )
    val 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)

    // :: 符号的使用
    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")
    // 下面等价 4 :: 5 :: 6 :: list1
    val list6 = 4 :: 5 :: 6 :: list4 ::: Nil
    println("list6=" + list6)
  }
}

输出结果如下:

代码语言:javascript
复制
List(1, 2, 3, Hello)
List()
value1=2
====================list追加元素后的效果====================
List(1, 2, 3, abc)
List(1, 2, 3, abc, 4)
list3=List(10, 1, 2, 3, abc)
list5=List(4, 5, 6, List(1, 2, 3, abc))
list6=List(4, 5, 6, 1, 2, 3, abc)

List元素的追加练习题

10.8.4 ListBuffer

ListBuffer 是可变的 list 集合,可以添加、删除元素,ListBuffer 属于序列。 // 查看一下继承关系即可 Seq var listBuffer = ListBuffer(1, 2) 示例代码如下:

代码语言:javascript
复制
package com.atguigu.chapter10.list

import scala.collection.mutable.ListBuffer

object ListBufferDemo01 {
  def main(args: Array[String]): Unit = {
    // 创建 ListBuffer
    val list0 = ListBuffer[Int](1, 2, 3)
    println(list0) // ListBuffer(1, 2, 3)

    // 访问 ListBuffer 中的元素
    println("list0(2)=" + list0(2))
    // 遍历
    for (item <- list0) {
      println("item=" + item)
    }

    // 动态的增加元素,lst1 就会变化,增加一个一个的元素
    val list1 = new ListBuffer[Int] // 空的ListBuffer
    list1 += 4
    list1.append(5)
    println(list1) // ListBuffer(4, 5)

    list1.append(5, 6)
    println(list1) // ListBuffer(4, 5, 5, 6)

    list0 ++= list1
    println(list0) // ListBuffer(1, 2, 3, 4, 5, 5, 6)
    val list2 = list0 ++ list1
    println(list2) // ListBuffer(1, 2, 3, 4, 5, 5, 6, 4, 5, 5, 6)
    val list3 = list0 :+ 5
    println(list3) // ListBuffer(1, 2, 3, 4, 5, 5, 6, 5)

    println("==========删除==========")
    println("list1=" + list1) // lst1=ListBuffer(4, 5, 5, 6)
    list1.remove(1)  // 表示将索引为1的元素删除(索引从0开始)
    for (item <- list1) {
      println("item=" + item)
    }

  }
}

输出结果如下:

代码语言:javascript
复制
ListBuffer(1, 2, 3)
list0(2)=3
item=1
item=2
item=3
ListBuffer(4, 5)
ListBuffer(4, 5, 5, 6)
ListBuffer(1, 2, 3, 4, 5, 5, 6)
ListBuffer(1, 2, 3, 4, 5, 5, 6, 4, 5, 5, 6)
ListBuffer(1, 2, 3, 4, 5, 5, 6, 5)
==========删除==========
list1=ListBuffer(4, 5, 5, 6)
item=4
item=5
item=6

10.9 队列 Queue

队列的应用场景:银行排队的案例。

队列的说明

补充:操作符的重载 演示 示例代码如下:

代码语言:javascript
复制
package com.atguigu.chapter10.queue

/**
  * 操作符的重载
  */
object OperatorOverloadDemo {
  def main(args: Array[String]): Unit = {
    val cat = new Cat
    cat + 10
    cat + 20
    println("cat.age=" + cat.age)
    cat.+(9)
    println("cat.age=" + cat.age)
  }
}

class Cat {
  var age = 0

  def +(n: Int): Unit = {
    this.age += n
  }
}

输出结果如下:

代码语言:javascript
复制
cat.age=30
cat.age=39
10.9.1 队列的创建+追加数据
10.9.2 删除和加入队列元素+返回队列元素

10.9.1~10.9.2示例代码如下:

代码语言:javascript
复制
package com.atguigu.chapter10.queue

import scala.collection.mutable

object QueueDemo01 {
  def main(args: Array[String]): Unit = {
    // 说明: 这里的 Int 是泛型,表示 q1 队列只能存放 Int 类型。
    // 如果希望 q1 可以存放其它类型,则使用 Any 即可。
    val q1 = new mutable.Queue[Int]
    println(q1) // Queue()

    // 给队列增加元素
    q1 += 9
    println("q1=" + q1) // q1=Queue(9)

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

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

    println("==========删除和加入队列元素==========")
    // dequeue 从队列的头部取出元素,q1 本身会变
    val queueElement = q1.dequeue()
    println("queueElement=" + queueElement + " q1=" + q1) // queueElement=9 q1=Queue(4, 5, 7)

    // enQueue 入队列,默认是从队列的尾部加入,Redis
    q1.enqueue(100, 10, 100, 888)
    println("q1=" + q1) // q1=Queue(4, 5, 7, 100, 10, 100, 888)

    println("==========返回队列的元素==========")
    // 1. 获取队列的第一个元素
    println(q1.head) // 4  对q1没有任何影响
    // 2. 获取队列的最后一个元素
    println(q1.last) // 888 对q1没有任何影响
    // 3. 取出队尾的数据,即:返回除了第一个以外剩余的元素,可以级联使用,这个在递归时使用较多。
    println(q1.tail) // Queue(5, 7, 100, 10, 100, 888)
    println(q1.tail.tail.tail.tail) // Queue(10, 100, 888)
  }
}

输出结果如下:

代码语言:javascript
复制
Queue()
q1=Queue(9)
q1=Queue(9, 4, 5, 7)
==========删除和加入队列元素==========
queueElement=9 q1=Queue(4, 5, 7)
q1=Queue(4, 5, 7, 100, 10, 100, 888)
==========返回队列的元素==========
4
888
Queue(5, 7, 100, 10, 100, 888)
Queue(10, 100, 888)

10.10 映射 Map

10.10.1 Map 的基本介绍

Java 中的 Map 回顾   HashMap 是一个散列表(数组+链表),它存储的内容是键值对(key-value)映射,Java 中的 HashMap 是无序的,key 不能重复。 示例代码如下:

代码语言:javascript
复制
package com.atguigu.chapter10.map;

import java.util.HashMap;

public class JavaMapTest {
    public static void main(String[] args) {
        // Java中的HashMap是无序的,key不能重复。
        HashMap<String, Integer> hm = new HashMap();
        hm.put("no1", 100);
        hm.put("no2", 200);
        hm.put("no3", 300);
        hm.put("no4", 400);

        System.out.println(hm); // {no2=200, no1=100, no4=400, no3=300}
        System.out.println(hm.get("no2")); // 20
    }
}

输出结果如下:

代码语言:javascript
复制
{no2=200, no1=100, no4=400, no3=300}
200

Scala 中的 Map 介绍   Scala 中的 Map 和 Java 类似,也是一个散列表,它存储的内容也是键值对(key-value)映射,Scala 中不可变的 Map 是有序的,可变的 Map 是无序的。   Scala 中,有可变 Map (scala.collection.mutable.Map) 和 不可变 Map(scala.collection.immutable.Map)。

10.10.2 Map 的创建

方式1-构造不可变映射   Scala 中的不可变 Map 是有序,构建 Map 中的元素底层是 Tuple2 类型。 方式2-构造可变映射   需要指定可变 Map 的包。 方式3-创建空的映射   val map3 = new scala.collection.mutable.HashMap[String, Int] 方式4-对偶元组   即创建包含键值对的二元组,和第一种方式等价,只是形式上不同而已。   对偶元组:就是只含有两个数据的元组。

10.10.3 Map 的取值

方式1-使用 map(key)   1、如果 key 存在,则返回对应的值。   2、如果 key 不存在,则抛出异常 [java.util.NoSuchElementException]。   3、在 Java 中,如果 key 不存在则返回 null。 方式2-使用 contains 方法检查是否存在 key   使用 containts 先判断再取值,可以防止异常,并加入相应的处理逻辑。   1、如果key存在,则返回 true。   2、如果key不存在,则返回 false。 方式3-使用 map.get(key).get 取值   1、如果 key 存在 map.get(key) 就会返回 Some(值),然后 Some(值).get 就可以取出。   2、如果 key 不存在 map.get(key) 就会返回 None。 方式4-使用 map4.getOrElse() 取值   底层是:def getOrElse[V1 >: V](key: K, default: => V1)   1、如果key存在,返回key对应的值。   2、如果key不存在,返回默认值。在java中底层有很多类似的操作。 如何选择取值方式建议   如果我们确定 map 有这个 key,则应当使用 map(key),速度快。   如果我们不能确定 map 是否有 key,而且有不同的业务逻辑,使用 map.contains() 先判断再加入逻辑。   如果只是简单的希望得到一个值,使用 map4.getOrElse("ip", "127.0.0.1")

10.10.4 可变 Map 的修改、添加和删除

说明:   map 是可变的,才能修改,否则报错。   如果 key 存在:则修改对应的值,key 不存在,等价于添加一个 key-val。 说明:   "A","B" 就是要删除的 key, 可以写多个。   如果 key 存在,就删除,如果 key 不存在,也不会报错。

10.10.5 Map 的遍历

10.10.2~10.10.5的所有示例代码如下:

代码语言:javascript
复制
package com.atguigu.chapter10.map

import scala.collection.mutable

object ScalaMapDemo01 {
  def main(args: Array[String]): Unit = {
    println("====================1、Map 的创建====================")
    // 方式1-构造不可变映射
    // 1.默认 Map 是 immutable.Map
    // 2.key-value 类型支持 Any
    // 3.在 Map 的底层,每对 key-value 是元组 Tuple2
    // 4.从输出的结果看到,输出顺序和声明顺序一致
    val map1 = Map("Alice" -> 10, "Bob" -> 20, "Kotlin" -> "北京")
    println(map1) // Map(Alice -> 10, Bob -> 20, Kotlin -> 北京)


    // 方式2-构造可变映射(需要指定可变Map的包)
    // 1.从输出的结果看到,可变的 map 输出顺序和声明顺序不一致
    val map2 = mutable.Map("Alice" -> 10, "Bob" -> 20, "Kotlin" -> "北京")
    println(map2) // Map(Bob -> 20, Kotlin -> 北京, Alice -> 10)

    // 方式3-创建空的映射
    val map3 = new scala.collection.mutable.HashMap[String, Int]
    println("map3=" + map3) // map3=Map()

    // 方式4-对偶元组(即创建包含键值对的二元组, 和第一种方式等价,只是形式上不同而已)
    val map4 = mutable.Map(("Alice", 10), ("Bob", 20), ("Kotlin", "北京"))
    println("map4=" + map4) // map4=Map(Bob -> 20, Kotlin -> 北京, Alice -> 10)

    println("====================2、Map 的取值====================")
    // 方式1-使用 map(key)
    println(map4("Alice")) // 10
    // 抛出异常(java.util.NoSuchElementException: key not found:)
    // println(map4("Alice~~~"))

    // 方式2-使用 contains 方法检查是否存在 key。
    if (map4.contains("Alice")) {
      println("key存在,值=" + map4("Alice"))
    } else {
      println("key不存在:)")
    }

    // 方式3-使用 map.get(key).get 取值
    // 1. 如果 key 存在 map.get(key) 就会返回 Some(值),然后 Some(值).get 就可以取出。
    // 2. 如果 key 不存在 map.get(key) 就会返回 None。
    println(map4.get("Alice").get)
    // println(map4.get("Alice~~~").get) // 抛出异常 java.util.NoSuchElementException: None.get

    // 方式4-使用 map4.getOrElse() 取值  底层是:def getOrElse[V1 >: V](key: K, default: => V1)
    // 1. 如果key存在,返回key对应的值。
    // 2. 如果key不存在,返回默认值。在java中底层有很多类似的操作。
    println(map4.getOrElse("Alice~~~", "默认的值")) // 第一个参数是 key,第二个参数是 默认的值

    println("====================3、Map 的修改、添加和删除====================")
    val map5 = mutable.Map(("A", 1), ("B", "北京"), ("C", 3))
    println("map5=" + map5) // map5=Map(A -> 1, C -> 3, B -> 北京)
    map5("A") = 20 // 修改
    println("map5=" + map5) // map5=Map(A -> 20, C -> 3, B -> 北京)

    map5 += ("A" -> 100) // 如果 key 存在:则修改对应的值;如果 key 不存在,等价于添加一个 key-val
    // val map6 = map5 + ("E"->1, "F"->3) // 增加多个元素
    println("map5=" + map5) // map5=Map(A -> 100, C -> 3, B -> 北京)

    map5 -= ("A", "B", "AAA") // 删除多个元素,如果 key 存在,就删除,如果 key 不存在,也不会报错
    // val map6 = map5 - ("A", "B") // 删除多个元素
    println("map5=" + map5) // map5=Map(C -> 3)

    println("====================4、Map 的遍历====================")
    val map6 = mutable.Map(("A", 1), ("B", "北京"), ("C", 3))

    println("----------(k, v) <- map6----------")
    for ((k, v) <- map6) println(k + " is mapped to " + v)

    println("----------v <- map6.keys----------")
    for (v <- map6.keys) println(v)

    println("----------v <- map6.values----------")
    for (v <- map6.values) println(v)

    println("----------v <- map6----------")
    for (v <- map6) println(v + " key =" + v._1 + " val=" + v._2) // v 类型是 Tuple2
  }
}

输出结果如下:

代码语言:javascript
复制
====================1、Map 的创建====================
Map(Alice -> 10, Bob -> 20, Kotlin -> 北京)
Map(Bob -> 20, Kotlin -> 北京, Alice -> 10)
map3=Map()
map4=Map(Bob -> 20, Kotlin -> 北京, Alice -> 10)
====================2、Map 的取值====================
10
key存在,值=10
10
默认的值
====================3、Map 的修改、添加和删除====================
map5=Map(A -> 1, C -> 3, B -> 北京)
map5=Map(A -> 20, C -> 3, B -> 北京)
map5=Map(A -> 100, C -> 3, B -> 北京)
map5=Map(C -> 3)
====================4、Map 的遍历====================
----------(k, v) <- map6----------
A is mapped to 1
C is mapped to 3
B is mapped to 北京
----------v <- map6.keys----------
A
C
B
----------v <- map6.values----------
1
3
北京
----------v <- map6----------
(A,1) key =A val=1
(C,3) key =C val=3
(B,北京) key =B val=北京

10.11 集 Set

10.11.1 Set 基本介绍

Java 中 Set 的回顾   java 中,HashSet 是实现 Set<E> 接口的一个实体类,数据是以哈希表的形式存放的,里面的不能包含重复数据。Set 接口是一种不包含重复元素的 collection,HashSet 中的数据也是没有顺序的。 示例代码如下:

代码语言:javascript
复制
package com.atguigu.chapter10.set;

import java.util.HashSet;

public class JavaSetTest {
    public static void main(String[] args) {
        HashSet hs = new HashSet<String>();
        hs.add("jack");
        hs.add("tom");
        hs.add("jack");
        hs.add("jack2");
        System.out.println(hs); // [jack2, tom, jack]
    }
}

输出结果如下:

代码语言:javascript
复制
[jack2, tom, jack]

Scala 中的 Set 介绍 集是不重复元素的结合。集不保留顺序,默认是以哈希集实现。   默认情况下,Scala 使用的是不可变集合,如果你想使用可变集合,需要引用 scala.collection.mutable.Set 包。

10.11.2 Set 的创建

Set 不可变集合的创建 Set 可变集合的创建

10.11.3 Set 的取值
10.11.4 可变 Set 的修改、添加和删除

说明:   如果添加的对象已经存在,则不会重复添加,也不会报错。   Scala 的 Set 可以直接删除值。   如果删除的对象不存在,则不生效,也不会报错。

10.11.5 Set 的遍历

10.11.2~10.11.5的所有示例代码如下: 示例代码如下:

代码语言:javascript
复制
package com.atguigu.chapter10.set

import scala.collection.mutable

object ScalaSetDemo01 {
  def main(args: Array[String]): Unit = {
    println("====================1、Set 的创建====================")
    val set1 = Set(1, 2, 3) // 不可变
    println(set1)

    println(set1.max)
    println(set1.min)

    val set2 = mutable.Set(1, 2, "hello") // 可以变
    println(set2)

    println("====================2、Set 的取值====================")

    println("====================3、可变 Set 的修改、添加和删除====================")
    val set3 = mutable.Set(1, 2, 4, "abc")
    // 添加
    set3.add(90)  // 添加元素方式1,如果添加的对象已经存在,则不会重复添加,也不会报错。
    set3 += 78    // 添加元素方式2
    set3.+= (90)  // 添加元素方式3
    println(set3) // Set(78, 1, 2, abc, 90, 4)

    // 删除
    set3 -= 2 // 操作符形式,如果删除的对象不存在,则不生效,也不会报错。
    set3.remove("abc") // 方法的形式,Scala 的 Set 可以直接删除值。
    println(set3) // Set(78, 1, 90, 4)

    println("====================4、Set 的遍历====================")
    for(x <- set3) {
      println(x)
    }

  }
}

输出结果如下:

代码语言:javascript
复制
====================1、Set 的创建====================
Set(1, 2, 3)
3
1
Set(1, 2, hello)
====================2、Set 的取值====================
====================3、可变 Set 的修改、添加和删除====================
Set(78, 1, 2, abc, 90, 4)
Set(78, 1, 90, 4)
====================4、Set 的遍历====================
78
1
90
4

10.12 Set 的更多操作

查看集 Set 的更多使用方法,可以查看相关的文档。 Scala 官方API-2.11.8:https://www.scala-lang.org/api/2.11.8/#package

Set 常用方法列表

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-03-31 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第十章 数据结构(上)-集合
    • 10.1 数据结构特点
      • 10.1.1 Scala 集合基本介绍
      • 10.1.2 可变集合和不可变集合举例
    • 10.2 Scala 不可变集合继承层次一览图
      • 10.2.1 图
      • 10.2.2 小结
    • 10.3 Scala 可变集合继承层次一览图
      • 10.3.1 图
      • 10.3.2 小结
    • 10.4 数组-定长数组(声明泛型)
      • 10.4.1 第一种方式定义数组
      • 10.4.2 第二种方式定义数组
    • 10.5 数组-变长数组(声明泛型)
      • 10.5.1 变长数组分析小结
      • 10.5.2 定长数组与变长数组的转换
      • 10.5.3 多维数组的定义和使用
    • 10.6 数组-Scala 数组与 Java 的 List 的互转
      • 10.6.1 Scala 数组转 Java 的 List
      • 10.6.2 Java 的 List 转 Scala 数组(mutable.Buffer)
      • 10.6.3 补充一个多态的知识点(使用 trait 来实现参数多态)
    • 10.7 元组 Tuple
      • 10.7.1 元祖的基本介绍+元祖的创建
      • 10.7.2 元组的创建-代码小结
      • 10.7.3 元组数据的访问+遍历
    • 10.8 列表 List
      • 10.8.1 创建 List + List 元素的访问
      • 10.8.2 创建 List 的应用案例小结
      • 10.8.3 List 元素的追加
      • 10.8.4 ListBuffer
    • 10.9 队列 Queue
      • 10.9.1 队列的创建+追加数据
      • 10.9.2 删除和加入队列元素+返回队列元素
    • 10.10 映射 Map
      • 10.10.1 Map 的基本介绍
      • 10.10.2 Map 的创建
      • 10.10.3 Map 的取值
      • 10.10.4 可变 Map 的修改、添加和删除
      • 10.10.5 Map 的遍历
    • 10.11 集 Set
      • 10.11.1 Set 基本介绍
      • 10.11.2 Set 的创建
      • 10.11.3 Set 的取值
      • 10.11.4 可变 Set 的修改、添加和删除
      • 10.11.5 Set 的遍历
    • 10.12 Set 的更多操作
    相关产品与服务
    云数据库 Redis
    腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档