Appearance
首先来看一下整体的结构图,和Java不一样的是,Scala分为可变集合和不可变集合。
- 可变集合:在
scala.collection.mutable
这个包下面 - 不可变集合:在
scala.collection.immutable
这个包下面
TIP
- 我们在创建集合的时候,如果不指定具体的包名,默认会使用不可变集合,不可变集合在初始化后无法修改。
Set集合的使用
Set集合分为可变的和不可变的集合,默认情况下使用的是不可变集合,定义方式:val s = Set(1,2,3)
scala
val s = Set(1,2,3)
s += 4 // 会报错,因为默认创建的是不可变集合
s + 4 // 可以正常输出,因为创建了新的集合
创建可变集合:
scala
val s = scala.collection.mutable.Set(1,2,3)
s += 4
Set集合的子类
Set常用子类有: HashSet、LinkedHashSet、SortedSet。
- HashSet:元素不重复、无序
- LinkedHashSet:集合中的元素不重复、有序,它会用一个链表维护插入顺序, 可以保证集合中元素是有序的
- SortedSet:集合中的元素不重复、有序,它会自动根据元素来进行排序
- 如果在创建集合的时候就初始化了元素,则可以省略泛型的定义,集合会自动识别元素的类型
scala
// 1.使用HashSet,可以new也可以不new,因为HashSet既是class又是object,但是包名需要指定
val s = new scala.collection.mutable.HashSet[Int]()
// 2.使用LinkedHashSet
val s = new scala.collection.mutable.LinkedHashSet[Int]()
s += 1
s += 5
s += 2
print(s)
最后再来看一下SortedSet
scala
// 使用SortedSet,不可以使用new
val s = scala.collection.mutable.SortedSet[String]()
s += ("c")
s += ("a")
s += ("b")
scala> print(s)
TreeSet(a, b, c)
for循环迭代
scala
scala> for (i <- s) print(i + "\t")
a b c
List集合的使用
List代表一个不可变的列表,属于Seq接口的子接口。
scala
val list1 = List(1, 2, 3, 4)
针对List有head
、tail
以及::
这几个操作:
head
:返回列表的第一个元素。如果列表为空,则抛出异常。tail
:返回除第一个元素外的其他元素组成的新列表,如果列表为空,则返回空列表。::
:用于将一个元素添加到列表的开头。它是一个二元操作符,左边是要添加的元素,右边是原始列表。例如1 :: Nil
表示一个只包含元素1的新列表。
scala
scala> list1.head
res10: Int = 1
scala> list1.tail
res11: List[Int] = List(2, 3, 4)
scala> list1.head :: list1.tail
res12: List[Int] = List(1, 2, 3, 4)
scala> for(i <- list1) print(i+"\t")
1 2 3 4
ListBuffer
List作为不可变集合在工作中用起来很不方便,ListBuffer支持动态添加和移除元素。
scala
scala> val list2 = scala.collection.mutable.ListBuffer[Int]()
list2: scala.collection.mutable.ListBuffer[Int] = ListBuffer()
scala> list2 += 1
res14: list2.type = ListBuffer(1)
scala> list2 += 2
res15: list2.type = ListBuffer(1, 2)
scala> list2 -= 2
res16: list2.type = ListBuffer(1)
Map集合的使用
Map是一种可迭代的键值对(key/value)结构,
scala
// 创建不可变Map
val ages = Map("jack"->30,"tom"->25,"jessic"->23)
ages("jack")
// 创建不可变Map集合写法2
val ages = Map(("jack", 30), ("tom", 25), ("jessic", 23))
ages("jack")
// 遍历
for((key, value) <- ages) println(key + ":" + value)
// 遍历key
for(key <- ages.keys) println(key)
// 遍历value
for(v <- ages.values) println(v)
可变Map集合有一些常用操作:
put(key, value)
:向Map中添加一个键值对。如果Map中已存在该键,则旧值将被替换。get(key)
:根据键获取对应的值。如果Map中不存在该键,则返回None。remove(key)
:删除Map中的某个键值对,并返回被删除的值。如果Map中不存在该键,则返回None。keys
/keySet
:获取Map中所有的键,返回一个包含所有键的集合。values
:获取Map中所有的值,返回一个包含所有值的集合。contains
:查询map的key是否存在getOrElse
:如果key存在则赋值,否则有个默认值foreach { case (key, value) => }
:遍历Map中的每一个键值对,对每一个元素执行给定的操作。
scala
// 创建可变Map集合
scala> val map1 = scala.collection.mutable.Map("jack"->30,"tom"->25,"jessic"->23)
map1: scala.collection.mutable.Map[String,Int] = Map(jessic -> 23, jack -> 30, tom -> 25)
// 新增
scala> map1.put("key1",70)
res19: Option[Int] = None
// 修改
scala> map1("key1") = 99
// 移除
scala> map1 -= "key1"
scala> map1("key2") // 查询不存在的key会报错
java.util.NoSuchElementException: key not found: key2
at scala.collection.MapLike.default(MapLike.scala:236)
at scala.collection.MapLike.default$(MapLike.scala:235)
at scala.collection.AbstractMap.default(Map.scala:65)
// 判断Key是否存在
scala> map1.contains("key2")
res22: Boolean = false
// 如果key存在则赋值,否则默认值为0
scala> val age = if (map1.contains("key1")) map1("key1") else 0
age: Int = 70
// 更简答的写法
scala> val age = map1.getOrElse("key1", 12)
age: Int = 70
// 增加多个元素
map1 += ("zhangsan" -> 92, "lisi" -> 18)
Map集合的子类
- HashMap:是一个按照key的hash值进行排列存储的map
- SortedMap:不可变,可以自动对Map中的key进行排序【有序的map】
- LinkedHashMap:可变,可以记住插入的key-value的顺序
scala
// 创建SortedMap
scala> val ages1 = scala.collection.mutable.SortedMap("b" -> 30, "a" -> 29)
ages1: scala.collection.mutable.SortedMap[String,Int] = TreeMap(a -> 29, b -> 30)
// 创建LinkedHashMap
scala> val ages2 = new scala.collection.mutable.LinkedHashMap[String, Int]()
ages2: scala.collection.mutable.LinkedHashMap[String,Int] = Map()
scala> ages2("b") = 30
scala> ages2("a") = 19
scala> ages2("c") = 17
scala> print(ages2)
Map(b -> 30, a -> 19, c -> 17)
Array数组的使用
Array和Java的数组类似,长度不可变,Scala数组的底层实际上就是Java数组,双方可以互相调用。
scala
scala> val a = new Array[Int](10)
a: Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
scala> a(0)
res39: Int = 0
scala> a(0)=1
scala> a(0)
res41: Int = 1
也可以直接使用Array()创建数组,元素类型自动推断。
scala
scala> val a = Array("hello", "world")
a: Array[String] = Array(hello, world)
scala> a(0)
res42: String = hello
ArrayBuffer
与Java中的ArrayList类似,长度可变,支持添加元素、移除元素,如果不想每次都使用全限定名,则可以预先导入ArrayBuffer类。
scala
import scala.collection.mutable.ArrayBuffer
定义一个空的ArrayBuffer,使用+=
添加元素,可以添加多个。
scala
scala> val b = new ArrayBuffer[Int]()
b: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()
scala> b += 1
res44: b.type = ArrayBuffer(1)
scala> b += (2, 3, 4, 5)
res45: b.type = ArrayBuffer(1, 2, 3, 4, 5)
使用insert()
函数可以在指定位置插入元素,但是这种操作效率很低,因为需要移动指定位置后的所有元素。remove()
可以删除元素。
scala
scala> b.insert(3, 30)
scala> print(b)
ArrayBuffer(1, 2, 3, 30, 4, 5)
scala> b.remove(3) // remove按照下标进行删除
res48: Int = 30
scala> print(b)
ArrayBuffer(1, 2, 3, 4, 5)
TIP
注意:Array与ArrayBuffer可以互相进行转换,b.toArray
和a.toBuffer
。
数组常见操作
求和、求最大值、数组排序
scala
scala> val a = Array(3, 2, 1, 4, 5)
a: Array[Int] = Array(3, 2, 1, 4, 5)
scala> val sum = a.sum
sum: Int = 15
scala> val max = a.max
max: Int = 5
// 排序
scala> scala.util.Sorting.quickSort(a)
scala> a
res51: Array[Int] = Array(1, 2, 3, 4, 5)
Tuple
Tuple称为元组,与Array类似,都是不可变的,但与数组不同的是元组可以包含不同类型的元素,Tuple中的元素角标从1
开始。
scala
scala> val t = (1, 3.14, "hehe")
t: (Int, Double, String) = (1,3.14,hehe)
scala> t._1
res52: Int = 1
scala> t._2
res53: Double = 3.14
TIP
注意:目前 Scala 支持的元组最大长度为 22 ,对于更大长度可以使用集合或数组。