10.1 数据结构特点
10.1.1 Scala集合基本介绍
uml => 统一建模语言
1) Scala同时支持不可变集合和可变集合,不可变集合可以安全的并发访问
两个主要的包
不可变集合:scala.collection.immutable
可变集合:scala.collection.mutable
2) Scala默认采用不可变集合,对于几乎所有的集合类,Scala都同时提供了可变(mutable)和不可变(immutable)的版本
3) Scala的集合有三大类:序列Seq(有序的,Linear Seq),集Set,映射Map[key -> value],所有的集合都扩展自Iterable特质,在Scala中集合有可变(mutable)和不可变(immutable)
10.1.2 可变集合和不可变集合举例
1) 不可变集合:Scala不可变集合,就是集合本身不能动态变化(类似Java的数组,是不可以动态增长的)
2) 可变集合:可变集合,就是这个集合本身可以动态变化(比如:ArrayList,是可以动态增长的)
3) 使用Java做了一个简单的案例
import java.util.ArrayList; public class JavaCollection { public static void main(String[] args) { //不可变集合类似java的数组 int[] nums = new int[3]; nums[2] = 6; //? nums[2] = 7; //nums[3] = 8; //? // String[] names = {"bj", "sh"}; // System.out.println(nums + " " + names); // // //可变集合举例 ArrayList al = new ArrayList<String>(); al.add("狗蛋"); al.add("铁蛋"); System.out.println(al + " 地址= " + al.hashCode()); //地址 al.add("熊大"); System.out.println(al + " 地址2=" + al.hashCode()); //地址 } }
10.2 不可变集合继承层次一览图
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也是属于IndexedSeq
5) 经典的数据结构比如Queue和Stack被归属到LinearSeq
6) 注意Scala中的Map体系中有一个SortedMap,说明Scala的Map可以支持排序
7) IndexSeq和LinearSeq的区别[IndexSeq是通过索引来查找和定位,因此速度快,比如String就是一个索引集合,通过索引即可定位] [LinearSeq是线型的,即有头尾的概念,这种数据结构一般是通过遍历来查找,它的价值在于应用到一些具体的应用场景(电商网站,大数据推荐系统:最近浏览的10个商品)]
10.3 可变集合继承层次一览图
10.3.1 图
10.3.2 对上图的说明
1) 在可变集合中比不可变集合更丰富
2) 在Seq集合中,增加了Buffer集合,常用的有ArrayBuffer和ListBuffer
3) 如果涉及到线程安全问题可以选择使用syn...开头的集合
10.4 数组-定长数组(声明泛型)
10.4.1 第一种方式定义数组
-说明
这里的数组等同于Java中的数组,中括号的类型就是数组的类型
val arr = new Array[Int](10)
arr(1) = 9
-案例演示
object boke_demo01 { def main(args: Array[String]): Unit = { //说明 //1. 创建了一个Array对象, //2. [Int] 表示泛型,即该数组中,只能存放Int //3. [Any] 表示 该数组可以存放任意类型 //4. 在没有赋值情况下,各个元素的值 0 //5. arr(3) = 10 表示修改 第4个元素的值 val arr = new Array[Int](4) //底层 int[] arr = new int[4] println(arr.length) // 4 println("arr(0)=" + arr(0)) // 0 //数据的遍历 for (i <- arr) { println(i) } println("--------------------") arr(3) = 10 // for (i <- arr) { println(i) } } }
10.4.2 第二种方式定义数组
-说明
在定义数组时,直接赋值
//使用apply方法创建数组对象
val arr = Apply(1,2)
-案例演示
object boke_demo01 { def main(args: Array[String]): Unit = { //说明 //1. 使用的是 object Array 的apply //2. 直接初始化数组,这时因为你给了 整数和 "", 这个数组的泛型就Any //3. 遍历方式一样 var arr = Array(1, 3, "xx") arr(1) = "xx" for (i <- arr) { println(i) } //可以使用我们传统的方式遍历,使用下标的方式遍历 for (index <- 0 until arr.length) { printf("arr02[%d]=%s", index, arr(index) + "\t") } } }
10.5 数组-变长数组[声明泛型]
-说明
//定义/声明
val arr = ArrayBuffer[Int]()
//追加值/元素
arr.append(9)
//重新赋值
arr(0) = 6
-案例演示
object boke_demo01 { def main(args: Array[String]): Unit = { //创建ArrayBuffer val arr = ArrayBuffer[Any](3, 2, 5) //访问,查询 //通过下标访问元素 println("arr(1)=" + arr(1)) // arr(1) = 2 //遍历 for (i <- arr) { println(i) } println(arr.length) //3 println("arr.hash=" + arr.