一. 数据结构特点
1. 集合基本介绍
- Scala同时支持不可变集合和可变集合
- 两个主要的包:
不可变集合:scala.collection.immutable
可变集合: scala.collection.mutable - Scala默认采用不可变集合,对于几乎所有的集合类,Scala都同时提供了可变(mutable)和不可变(immutable)的版本
- Scala的集合有三大类:序列Seq、集Set、映射Map,所有的集合都扩展自Iterable特质,在Scala中集合有可变(mutable)和不可变(immutable)两种类型。
2. 可变集合和不可变集合
-
不可变集合:scala不可变集合,就是这个集合本身不能动态变化。(类似java的数组,是不可以动态增长的)
-
可变集合:可变集合,就是这个集合本身可以动态变化的。(比如:ArrayList , 是可以动态增长的)
二. 元组
1. 基本介绍
- 元组也是可以理解为一个容器,可以存放各种相同或不同类型的数据。说的简单点,就是将多个无关的数据封装为一个整体,称为元组, 最大的特点灵活,对数据没有过多的约束
- 注意: 元组中最多只能有22个元素
2. 元组的创建
- 代码
// 方式1 val tuple1 = (1, 2, true, "a", 'c') println(tuple1) // (1,2,true,a,c) // 方式2 val tuple2: (String, String) = "one" -> "two" println(tuple2) // (one,two) val tuple3: ((String, String), String) = "one" -> "two" -> "three" println(tuple3) // ((one,two),three) // 方式3, 有n个元素, 就使用Tuple n val tuple4: (Int, Int, Int) = Tuple3(1, 2, 3) println(tuple4) // (1,2,3)
3. 元组数据访问
访问元组中的数据,可以采用顺序号(_顺序号),也可以通过索引(productElement)访问。
- 代码
val tuple1 = (1, 2, true, "a", 'c') println(tuple1._2) // 2 println(tuple1._5) // c
4. 元组数据的遍历
tuple1是一个整体, 遍历需要调其迭代器:
productIterator
-
代码
val tuple1 = (1, 2, true, "a", 'c') // tuple1是一个整体, 遍历需要调其迭代器 for(ele <- tuple1.productIterator) { print(ele + " ") // 1 2 true a c }
三. 数组
1. 定长数组
1. 创建数组
-
方式1:
val arr1: Array[Int] = new Array[Int](5)
-
方式2:
val arr2: Array[Any] = Array("hello", 1, 2, true, 'A')
2. 遍历数组
-
for
for(ele <- arr2) { print(ele + " ") }
-
foreach
arr2.foreach(println(_))
2. 可变长数组
需要导入:
import scala.collection.mutable._
1. 创建数组
-
val arr1: ArrayBuffer[Any] = ArrayBuffer(1, 2, true, 'A', "hello") val arr2: ArrayBuffer[Int] = new ArrayBuffer[Int](3)
2. 追加元素: append
-
arr1.append(false)
3. 删除元素: remove
-
// 删除指定下标的元素 arr1.remove(2)
4. 变长数组分析小结
- ArrayBuffer是变长数组,类似java的ArrayList
- val arr2 = ArrayBufferInt 也是使用的apply方法构建对象
- def append(elems: A*) { appendAll(elems) } 接收的是可变参数.
- 每append一次,arr在底层会重新分配空间,进行扩容,arr2的内存地址会发生变化,也就成为新的ArrayBuffer
3. 类型转换
1. 定长数组与变长数组的转换
-
转换
arr1.toBuffer //定长数组转可变数组
arr2.toArray //可变数组转定长数组 -
说明
arr2.toArray 返回结果才是一个定长数组, arr2本身没有变化
arr1.toBuffer返回结果才是一个可变数组, arr1本身没有变化
2. Scala数组转Java的List
-
// Scala集合和Java集合互相转换 val arr = ArrayBuffer("1", "2", "3") import scala.collection.JavaConversions.bufferAsJavaList val javaArr = new ProcessBuilder(arr) val arrList = javaArr.command() println(arrList)
3. Java的List转Scala数组(mutable.Buffer)
-
import scala.collection.JavaConversions.asScalaBuffer import scala.collection.mutable // java.util.List ==> Buffer val scalaArr: mutable.Buffer[String] = arrList scalaArr.append("jack") println(scalaArr)
四. 列表(List)
Scala中的List 和Java List 不一样,在Java中List是一个接口,真正存放数据是ArrayList,而Scala的List可以直接存放数据,就是一个object,默认情况下Scala的List是不可变的,List属于序列Seq。
1. 创建列表
-
val list1: List[Int] = List(1, 2, 3) // 创建空集合 val list2 = Nil
- List 在 scala包对象声明的,因此不需要引入其它包也可以使用
- val List = scala.collection.immutable.List
- List 中可以放任何数据类型,比如 arr1的类型为 List[Any]
- 如果希望得到一个空列表,可以使用Nil对象, 在 scala包对象声明的,因此不需要引入其它包也可以使用
val Nil = scala.collection.immutable.Nil
2. 追加元素
向列表中增加元素, 会返回新的列表/集合对象, 并不会在原来的基础上增加
-
在列表的后面增加元素:
:+
val list3: List[Int] = list1 :+ 4
-
在列表的前面增加元素 :
+:
val list4: List[Int] = 5 +: list3
-
在列表的最后增加元素
::
表示向集合中 新建集合添加元素。
:::
运算符是将集合中的每一个元素加入到集合中val list1: List[Int] = List(1, 2, 3) val list2 = Nil val list3 = 5 :: list1 :: 2 :: list2 val list4 = 5 :: list1 ::: 2 :: list2 println(list3) println(list4)
3. ListBuffer
ListBuffer是可变的list集合,可以添加,删除元素,ListBuffer属于序列
-
代码
val lb1: ListBuffer[Int] = ListBuffer(1, 2, 2, 4) println(lb1) // 末尾追加 lb1.append(3, 7) println(lb1) // 移除下标为4的元素 lb1.remove(4) println(lb1) // 从下标为2开始移除2个元素 lb1.remove(2, 2) println(lb1)
五. 队列(Queue)
1. 说明
- 队列是一个有序列表,在底层可以用数组或是链表来实现。
- 其输入和输出要遵循先入先出的原则。即:先存入队列的数据,要先取出。后存入的要后取出
- 在Scala中,由设计者直接给我们提供队列类型使用。
- 在scala中, 有 scala.collection.mutable.Queue 和 scala.collection.immutable.Queue , 一般来说,我们在开发中通常使用可变集合中的队列。
2. 追加元素
-
val queue: Queue[Int] = new Queue[Int]() // 添加一个元素 queue += 1 println(queue) // 添加List queue ++= List(2, 3, 4) println(queue) // 追加元素 queue.enqueue(10, 11, 12) println(queue)
3. 删除元素
-
queue.dequeue()
4. 返回队列中的元素
-
val queue: Queue[Int] = new Queue[Int]() // 追加元素 queue.enqueue(10, 11, 12, 13, 14, 15) println(queue) // 返回第一个元素 println(queue.head) // 返回最后一个元素 println(queue.last) // 返回队尾元素. 除第一个以外的剩余元素 println(queue.tail) println(queue.tail.tail)
六. Map
1. 基本介绍
- Scala中的Map 和Java类似,也是一个散列表,它存储的内容也是键值对(key-value)映射,Scala中不可变的Map是有序的,可变的Map是无序的。
- Scala中,有可变Map (scala.collection.mutable.Map) 和 不可变Map(scala.collection.immutable.Map)
2. 构造Map
1. 构造不可变Map
Scala中的不可变Map是有序,构建Map中的元素底层是Tuple2类型
-
val map1: Map[String, Int] = Map("one" -> 1, "two" -> 2, "three" -> 3) println(map1)
- 从输出的结果看到,输出顺序和声明顺序一致
- 构建Map集合中,集合中的元素其实是Tuple2类型
- 默认情况下(即没有引入其它包的情况下),Map是不可变map
2. 构造可变Map
导入:
import scala.collection.mutable
-
val map2: mutable.Map[String, Int] = mutable.Map("one" -> 1, "two" -> 2, "three" -> 3) println(map2)
- 从输出的结果看到,输出顺序和声明顺序不一致
3. 创建空Map
-
val map3: mutable.Map[String, Int] = new mutable.HashMap[String, Int] println(map3)
4. 创建对偶Map
即创建包含键值对的二元组, 和第一种方式等价,只是形式上不同而已。
对偶元组 就是只含有两个数据的元组。
-
val map4: mutable.Map[String, Int] = mutable.Map[String, Int](("A", 1), ("B", 2), ("C", 3)) println(map4)
3. Map取值
1. 使用map(key)
-
val map1: Map[String, Int] = Map("one" -> 1, "two" -> 2, "three" -> 3) println(map1) // 方式1: 使用map(key), 如果key不存在, 则会报错 // 使用contains方法检查是否存在key if (map1.contains("Two")) { println(map1("Two")) } else { println("map1 中不存在") }
2. 使用map.get(key).get取值
-
val map1: Map[String, Int] = Map("one" -> 1, "two" -> 2, "three" -> 3) println(map1) // 方式2: 使用map.get(key).get取值 if (map1.contains("four")) { println(map1.get("four").get) } else { println("map1 中不存在") }
3. 使用map.getOrElse()取值
-
val map1: Map[String, Int] = Map("one" -> 1, "two" -> 2, "three" -> 3) println(map1) // 方式3: 使用map.getOrElse()取值 // 如果key存在,返回key对应的值。 // 如果key不存在,返回默认值。 val value1: Any = map1.getOrElse("two", "不存在") val value2: Any = map1.getOrElse("four", "不存在") println(value1) println(value2)
4. 如何选择取值方式建议
- 如果我们确定key是存在的,应该使用map(“key”) ,速度快.
- 如果我们不确定key是否存在, 而且在不存在时,有业务逻辑处理就是用map.contains() 配合 map(“key”)
- 如果只是简单的希望返回一个值,就使用getOrElse()
4. 添加元素
1. 添加单个元素
-
map4 += ( "D" -> 4 ) map4 += ( "B" -> 50 )
2. 添加多个元素
-
val map4 = mutable.Map( ("A", 1), ("B", "北京"), ("C", 3) ) val map5 = map4 + ("E"->1, "F"->3) map4 += ("EE"->1, "FF"->3)
5. 删除元素
-
val map4 = mutable.Map( ("A", 1), ("B", "北京"), ("C", 3) ) map4 -= ("A", "B")
- 说明:
如果key存在, 就删除; 如果key不存在, 并不会报错
6. Map遍历
-
val map1: Map[String, Int] = Map("one" -> 1, "two" -> 2, "three" -> 3) println(map1) // 遍历key - value for (ele <- map1) { println(ele) } for ((k, v) <- map1) { println(k + "---" + v) } // 遍历key for (k <- map1.keys) { println(k) } // 遍历value for (v <- map1.values) { println(v) }
七. Set
1. 基本介绍
- 集是不重复元素的结合。集不保留顺序,默认是以哈希集实现
- 默认情况下,Scala 使用的是不可变集合,如果你想使用可变集合,需要引用
scala.collection.mutable.Set
包
2. Set创建
1. 创建不可变set
-
val set = Set(1, 2, 3) //不可变 println(set)
2. 创建可变set
-
import scala.collection.mutable.Set val mutableSet = Set(1, 2, 3) //可变
3. 添加元素
如果添加的对象已经存在,则不会重复添加
-
val set1: mutable.Set[Int] = mutable.Set(1, 2, 3) // 方式1: 一次智能添加一个 set1.add(5) // 方式2: 一次只能加一个 set1 += 7 // 方式3: 可以添加多个 set1 += (4, 5) println(set1)
4. 删除元素
如果添加的对象不存在,不会报错
-
val set1: mutable.Set[Int] = mutable.Set(1, 2, 3, 5, 4, 6) // 方式1: 一次只能删除一个元素 set1.remove(5) println(set1) // 方式2: 一次只能删除一个元素 set1 -= 2 println(set1) // 方式3: 可以删除多个 set1 -= (1, 6) println(set1)
5. 遍历元素
-
val set1: mutable.Set[Int] = mutable.Set(1, 2, 3, 5, 4, 6) // 方式1 for (ele <- set1) { println(ele) } // 方式2 set1.foreach(println(_))
声明:
- 本文参考了尚硅谷Scala课程的课件