第十章 数据结构(上)-集合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 的 List10.6.2 Java 的 List 转 Scala 数组(mutable.Buffer)10.6.3 补充一个多态的知识点(使用 trait 来实现参数多态)10.7 元组 Tuple10.7.1 元祖的基本介绍+元祖的创建10.7.2 元组的创建-代码小结10.7.3 元组数据的访问+遍历10.8 列表 List10.8.1 创建 List + List 元素的访问10.8.2 创建 List 的应用案例小结10.8.3 List 元素的追加10.8.4 ListBuffer10.9 队列 Queue10.9.1 队列的创建+追加数据10.9.2 删除和加入队列元素+返回队列元素10.10 映射 Map10.10.1 Map 的基本介绍10.10.2 Map 的创建10.10.3 Map 的取值10.10.4 可变 Map 的修改、添加和删除10.10.5 Map 的遍历10.11 集 Set10.11.1 Set 基本介绍10.11.2 Set 的创建10.11.3 Set 的取值10.11.4 可变 Set 的修改、添加和删除10.11.5 Set 的遍历10.12 Set 的更多操作


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

10.1 数据结构特点

10.1.1 Scala 集合基本介绍

10.1.2 可变集合和不可变集合举例


示例代码如下:

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

输出结果如下:

[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 中的数组,中括号的类型就是数组的类型。

val arr1 = new Array[Int](10)
// 赋值,集合元素采用小括号访问
arr1(1) = 7

示例代码如下:

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

输出结果如下:

4
arr01(0)=0
0
0
0
0
----------
0
0
0
10

10.4.2 第二种方式定义数组

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

// 使用 apply 方法创建数组对象
val arr1 = Array(1, 2)

示例代码如下:

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

输出结果如下:

1
xx
xxx
arr02[0]=1    arr02[1]=xx arr02[2]=xxx

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

说明:

// 定义/声明
val arr2 = ArrayBuffer[Int]()
// 追加值/元素
arr2.append(7)
// 重新赋值
arr2(0) = 7

示例代码如下:

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

输出结果如下:

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 定长数组与变长数组的转换


示例代码如下:

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

输出结果如下:

ArrayBuffer(1, 2, 3)
[I@7a79be86
newArr2.hash=387518613
newArr2.hash=-1552340494
ArrayBuffer(1, 2, 3, 123)

10.5.3 多维数组的定义和使用

说明

// 定义
val arr = Array.ofDim[Double](3, 4)
// 说明:二维数组中有三个一维数组,每个一维数组中有四个元素 // 赋值
arr(1)(1) = 11.11

示例代码如下:

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

输出结果如下:

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 数组,看下面案例:
示例代码如下:

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

输出结果如下:

[1, 2, 3]

10.6.2 Java 的 List 转 Scala 数组(mutable.Buffer)

示例代码如下:

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

输出结果如下:

[1, 2, 3]
ArrayBuffer(2, 3, jack, tom)

10.6.3 补充一个多态的知识点(使用 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)

10.7 元组 Tuple

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


示例代码如下:

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

输出结果如下:

(1,2,3,hello,4)

10.7.2 元组的创建-代码小结

10.7.3 元组数据的访问+遍历


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

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

输出结果如下:

(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 元素的访问


示例代码如下:

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

输出结果如下:

List(1, 2, 3, Hello)
List()
value1=2

10.8.2 创建 List 的应用案例小结

10.8.3 List 元素的追加

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


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

示例代码如下:

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

输出结果如下:

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)
示例代码如下:

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

输出结果如下:

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

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


队列的说明

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

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

输出结果如下:

cat.age=30
cat.age=39

10.9.1 队列的创建+追加数据

10.9.2 删除和加入队列元素+返回队列元素

10.9.1~10.9.2示例代码如下:

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

输出结果如下:

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 不能重复
示例代码如下:

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

输出结果如下:

{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-使用 map.getOrElse(key, defaultvalue) 取值
  底层是: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的所有示例代码如下:

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(key, defaultvalue) 取值  底层是: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
  }
}

输出结果如下:

====================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 中的数据也是没有顺序的。
示例代码如下:

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

输出结果如下:

[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的所有示例代码如下:
示例代码如下:

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

输出结果如下:

====================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 常用方法列表

大数据技术之_16_Scala学习_07_数据结构(上)-集合的更多相关文章

  1. 大数据技术之_16_Scala学习_08_数据结构(下)-集合操作+模式匹配

    第十一章 数据结构(下)-集合操作11.1 集合元素的映射-map11.1.1 map 映射函数的操作11.1.2 高阶函数基本使用案例1+案例211.1.3 使用 map 映射函数来解决11.1.4 ...

  2. 大数据技术之_16_Scala学习_01_Scala 语言概述

    第一章 Scala 语言概述1.1 why is Scala 语言?1.2 Scala 语言诞生小故事1.3 Scala 和 Java 以及 jvm 的关系分析图1.4 Scala 语言的特点1.5 ...

  3. 大数据技术之_16_Scala学习_04_函数式编程-基础+面向对象编程-基础

    第五章 函数式编程-基础5.1 函数式编程内容说明5.1.1 函数式编程内容5.1.2 函数式编程授课顺序5.2 函数式编程介绍5.2.1 几个概念的说明5.2.2 方法.函数.函数式编程和面向对象编 ...

  4. 大数据技术之_16_Scala学习_13_Scala语言的数据结构和算法_Scala学习之旅收官之作

    第十九章 Scala语言的数据结构和算法19.1 数据结构(算法)的介绍19.2 看几个实际编程中遇到的问题19.2.1 一个五子棋程序19.2.2 约瑟夫问题(丢手帕问题)19.2.3 其它常见算法 ...

  5. 大数据技术之_16_Scala学习_02_变量

    第二章 变量2.1 变量是程序的基本组成单位2.2 Scala 变量的介绍2.2.1 概念2.2.2 Scala 变量使用的基本步骤2.3 Scala 变量的基本使用2.4 Scala 变量使用说明2 ...

  6. 大数据技术之_16_Scala学习_05_面向对象编程-中级

    第七章 面向对象编程-中级7.1 包7.1.1 Java 中的包7.1.2 Scala 中的包7.1.3 Scala 包的特点概述7.1.4 Scala 包的命名7.1.5 Scala 会自动引入的常 ...

  7. 大数据技术之_16_Scala学习_06_面向对象编程-高级+隐式转换和隐式值

    第八章 面向对象编程-高级8.1 静态属性和静态方法8.1.1 静态属性-提出问题8.1.2 基本介绍8.1.3 伴生对象的快速入门8.1.4 伴生对象的小结8.1.5 最佳实践-使用伴生对象解决小孩 ...

  8. 大数据技术之_16_Scala学习_09_函数式编程-高级

    第十三章 函数式编程-高级13.1 偏函数(partial function)13.1.1 提出一个需求,引出思考13.1.2 解决方式-filter + map 返回新的集合13.1.3 解决方式- ...

  9. 大数据技术之_11_HBase学习_01_HBase 简介+HBase 安装+HBase Shell 操作+HBase 数据结构+HBase 原理

    第1章 HBase 简介1.1 什么是 HBase1.2 HBase 特点1.3 HBase 架构1.3 HBase 中的角色1.3.1 HMaster1.3.2 RegionServer1.3.3 ...

随机推荐

  1. hbase(0.94) get、scan源码分析

    简介 本文是需要用到hbase timestamp性质时研究源码所写.内容有一定侧重.且个人理解不算深入,如有错误请不吝指出. 如何看源码 hbase依赖很重,没有独立的client包.所以目前如果在 ...

  2. oracle 导入导出语句

    imp USERID/PSD@SID file='D:\1.dmp' full=y statistics=none exp USERID/PSD@SID file='D:\1.dmp' tables= ...

  3. [Leetcode] rotate image 旋转图片

    You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise). ...

  4. 【TMD模拟赛】黄金拼图 Cao

    正解:Cao 据说这样的题是用来骗丛林生物上树的...... 这样的题除了考观察力之外还.........我们发现他异或了opt,恩,就这样,用离线推答案..... #include <cstd ...

  5. C语言指针大杂烩

    By francis_hao Oct 31,2016 指针数组和数组指针 指针数组本身是个数组,数组的内容是指针.形如char *pa[].由于[]优先级高于*,pa先于[]结合表示pa是一个数组,p ...

  6. Codeforces Round #525 (Div. 2)D. Ehab and another another xor problem

    D. Ehab and another another xor problem 题目链接:https://codeforces.com/contest/1088/problem/D Descripti ...

  7. 安卓中使用iconfont

    https://www.cnblogs.com/dongweiq/p/5730212.html

  8. ng4转义html

    https://stackoverflow.com/questions/31548311/angular-html-binding <div [innerHTML]="content& ...

  9. 构建一个类jq的函数库

    jqfree core var $ = function(selector, context) { return new $.fn.init(selector, context); }; $.fn = ...

  10. CSS属性中cursor:hand

    在 IE 下设置鼠标为手型的方法: cursor: hand,但是在 FIREFOX 中是无效的,解决方法是在FIREFOX中设置: cursor: pointer. 而这个pointer 值在IE和 ...