0%

scala集合

scala集合

scala同时支持不可变集合和可变集合,不可变集合可以安全的并发访问,包含有三大类,Seq序列、Set集合、Map映射
不可变集合:scala.collection.immutable

集合本身不能动态变化

不可变集合

可变集合:scala.collection.mutable

集合本身是可以动态变化的

可变集合层级关系

在不指定确定采用哪个包时,默认采用的都是不可变集合,根据上面的继承关系可以看出,Scala的集合有三大类,序列Seq、集Set、映射Map,所有的集合都扩展自Iterator特质

数组

定长数组Array

数组定义方式一

1
2
3
4
5
6
7
8
9
10
11
12
13
// [Int]表示泛型,表明该数组只能存放Int,如果为Any,则表示可以存放任意类型
val array01 = new Array[Int](5)
// 长度5
println(array01.length)
// 默认值为0
println(array01(0))
println("----遍历----")
for(a <- array01){
println(a)
}
array01(1) = 10
println("赋值-------")
println(array01(1))

数组定义方式二

在定义数组时,直接赋值

1
2
3
4
5
// 实际上使用的是Array的apply方法
val array02 = Array(1,2,3)
for (a <- array02){
println(a)
}
数组的访问

直接使用索引来进行访问数据

1
array01(1)
数组的赋值

直接根据索引来赋值

1
array01(1) = 10

变长数组ArrayBuffer

ArrayBuffer与java的ArrayList类似,每次添加新的元素在底层都会重新分配空间,进行扩容,导致内存地址发生改变

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
val arrBuf = new ArrayBuffer[Int]
// 0
println("初始容量"+arrBuf.length)
// 473519988
println("初始"+arrBuf.hashCode())
arrBuf.addOne(10)
arrBuf.addOne(20)
arrBuf.append(30)
// 3
println("添加元素之后容量"+arrBuf.length)
// 573686093
println("添加元素之后"+arrBuf.hashCode())
println("----遍历------")
//10
//20
//30
for(a <- arrBuf){
println(a)
}
// 根据数组下标修改值
arrBuf(2) = 200

println("----修改之后遍历------")
//10
//20
//200
for(a <- arrBuf){
println(a)
}
// 根据数组下标删除值
arrBuf.remove(0)
println("----删除之后遍历------")
//20
//200
for(a <- arrBuf){
println(a)
}
// 在尾端添加元素
arrBuf += 1
// 在尾端添加元素
arrBuf += {2,3,4}

添加元素

可以使用addOne来添加新的元素

1
arrBuf.addOne(10)
修改元素

直接使用索引来修改值

1
arrBuf(2) = 200
删除元素

可以根据索引来删除该索引位置的元素

1
arrBuf.remove(0)
数组转换

定长数组和变长数组可以相互转换,定长数组调用toBuffer方法可以转换为变长数组,变长数组调用toArray方法可以转换为定长数组

多维数组

可以使用Array调用ofDim方法来生成多维数组

1
2
3
4
5
6
7
// 调用ofDim方法来生成多维数组
// 下面表示为一个二维数组,包含有3个一维数组,每个一维数组有4个元素
val arr = Array.ofDim[Int](3,4)
// 二维数组赋值
arr(1)(1) = 12

println(arr(1)(1))

元组Tuple

元组可以存放各种相同或不同类型的数据,将多个无关的数据封装为一个整体,元组最多只能有22个元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 为了高效的操作元组,编译器根据元素个数的不同,对应不同的元组类型,分别是Tuple1-Tuple22
val tuple = (1,2,"aa",4)
// (1,2,"aa",4)
println(tuple)
// class scala.Tuple4
println(tuple.getClass)
// _2获取元组的第二个元素 2
println(tuple._2)
// 根据模式匹配来根据_seq来获取元组的第二个元素 2
println(tuple.productElement(1))

//遍历 需要使用元组的迭代器来遍历
for(item <- tuple.productIterator){
println("元素="+item)
}

// 可以使用类型来严格控制每个元素的类型
val tuple1:(Int, Int, String, Int) = (1,2,"aa",4)

元组获取值

直接根据顺序号来获取值,顺序号从1开始

1
2
// 获取元组的第二个元素
tuple._2

也可以根据索引来获取,索引从0开始

1
2
// 获取元组的第二个元素
tuple.productElement(1)

列表List

scala中的List是一个object,是不可变的,属于Seq序列,如果需要使用可变的List,则使用ListBuffer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// List是不可变的
// 如果不指定确切的泛型,默认是List[Any]的
val list = List(1, 2, 3, "a")
//List(1, 2, 3, a)
println(list)

println("=====访问元素=====")
// 指定泛型
val listInt: List[Int] = List(1, 2, 3)

// 访问元素 从0开始
println(listInt(1))

println("=====添加新的元素=====")
// 对于List的操作,原始的List不会发生改变,只会返回一个新的List
// :在List一端 +在要添加的元素的一端
// :+表示追加到List的尾端
val listInt1 = listInt :+ 4
//原始List:List(1, 2, 3)
println("原始List:"+listInt)
//追加元素之后的List:List(1, 2, 3, 4)
println("追加元素之后的List:"+listInt1)
// +:表示插入到List的头部
val listInt2 = 0 +: listInt
//原始List:List(1, 2, 3)
println("原始List:"+listInt)
// 插入元素之后的List:List(0, 1, 2, 3)
println("插入元素之后的List:"+listInt2)

// 使用::可以向集合中添加多个元素,List一定要在最右边,运算是从右向左运行的
val listInt3 = 4 :: 5 :: listInt2
// List(4, 5, 0, 1, 2, 3)
println(listInt3)

Nil表示一个空列表,表示一个List()

1
2
3
4
// 空列表
val nilList = Nil
//List()
println(nilList)

获取元素

根据索引来获取元素值,索引从0开始

1
listInt(1)

添加元素

在列表最后追加元素

1
listInt :+ 4

在列表头部插入元素

1
0 +: listInt

:在List一端 +在要添加的元素的一端

也可以使用appended方法来追加元素

1
listInt.appended(5)

使用::来向集合中添加元素,多个元素就可以使用::连接起来

1
4 :: 5 :: listInt2

List一定要在最右边,运算是从右向左运行的,一个一个的插入到集合的头部

1
2
3
4
// 使用::是将该对象作为一个元素来插入到集合中的,如果中间有个集合,也会作为一个整体插入进去
val listInt4 = 12::13::listInt::listInt1
// List(12, 13, List(1, 2, 3), 1, 2, 3, 4)
println(listInt4)

使用:::可以解决将集合中的每一个元素加入到另一个元素中

1
2
3
4
// 使用:::可以将集合中的每一个元素插入到另一个集合中
val listInt5 = 12::13::listInt:::listInt1
// List(12, 13, 1, 2, 3, 1, 2, 3, 4)
println(listInt5)

删除元素

可以使用drop或者dropRight方法来删除元素

1
2
3
4
5
6
7
8
9
// drop表示的是从左往右开始删除几个元素
val listInt6 = listInt.drop(2)
// List(3)
println(listInt6)

// dropRight表示的是从右往左开始删除几个元素
val listInt7 = listInt.dropRight(2)
// List(1)
println(listInt7)

可变列表ListBuffer

ListBuffer是可变的List

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//ListBuffer是可变的List
val listBuffer: ListBuffer[Int] = ListBuffer(1, 2, 3)
// ListBuffer(1, 2, 3)
println(listBuffer)

// 获取第一个元素
println(listBuffer(0))

println("======遍历=======")
for (item <- listBuffer) {
println("元素:" + item)
}

// 创建一个空的ListBuffer
val listBuffer01 = new ListBuffer[Int]
// 追加元素
listBuffer01.append(2)
listBuffer01 += 4
// 把集合追加进去
listBuffer01 ++= listBuffer
// ListBuffer(2, 4, 1, 2, 3)
println(listBuffer01)

// remove删除使用的是下标
listBuffer01.remove(2)
// ListBuffer(2, 4, 2, 3)
println(listBuffer01)

获取元素

使用索引获取元素,索引从0开始

1
2
// 获取第一个元素
listBuffer(0)

添加元素

在列表最后追加元素,可以使用append方法,也可以使用+=

1
2
listBuffer01.append(2)
listBuffer01 += 4

如果需要将集合中的所有元素都追加到另一个集合,可以使用++=

1
listBuffer01 ++= listBuffer

使用insert方法在列表任意位置插入

1
2
//第一个参数表示索引位置,第二个参数为所要插入的元素值
listBuffer01.insert(1,10)

删除元素

使用remove方法根据索引来删除元素

1
listBuffer01.remove(2)

队列Queue

Queue是一个有序列表,遵循先入先出的原则,分为scala.collection.mutable.Queue可变队列和scala.collection.immutable.Queue不可变队列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 创建队列
val queue = new mutable.Queue[Int]

// +=追加单个元素
queue += 10
// ++=追加集合
queue ++= List(2,4,6,8)
// Queue(10, 2, 4, 6, 8)
println(queue)

// 入队 出队
// 入队 默认是加入到队尾
queue.enqueue(20)
// Queue(10, 2, 4, 6, 8, 20)
println(queue)

// 出队 默认从队首取出
queue.dequeue()
// Queue(2, 4, 6, 8, 20)
println(queue)

// 对Queue 本身不会有任何影响
// 获取Queue的第一个元素 2
println("队首元素:"+queue.head)
// 获取Queue的最后一个元素 20
println("队尾元素:"+queue.last)
// 返回除了第一个元素之外的剩余元素,返回的还是Queue,所以tail可以级联使用 queue.tail.tail
// Queue(4, 6, 8, 20)
println("队尾:"+queue.tail)

获取元素

使用head来获取队列第一个元素

1
queue.head

使用last来获取队列最后一个元素

1
queue.last

使用tail获取除第一个元素之外的队列,tail可以级联使用queue.tail.tail

1
queue.tail

上述操作都不会对队列本身产生影响,并没有删除队列中的数据

添加元素

添加元素都是追加到队尾的

使用+=添加单个元素

1
queue += 10

使用++=添加集合

1
queue ++= List(2,4,6,8)

入队操作

1
queue.enqueue(20)

删除元素

出队操作

1
queue.dequeue()

映射Map

scala的Map与java类似,但是scala中有可变的Map(scala.collection.mutable.Map)和不可变的Map(scala.collection.immutable.Map),可变的Map是无序的,不可变的Map是有序的,默认是不可变的Map

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
println("创建方式=======")
// 创建不可变的Map,Map底层每对key-value是一个Tuple2
// 不可变的Map可以直接使用,无需引包
val map = Map("张三" -> 10,"李四" -> 20)
println(map)

// 创建可变的Map
val map1 = mutable.Map("zs"-> 15)
println(map1)



// 创建空的Map
val map2 = new mutable.HashMap[String,Int]


println("存值操作========")
// key存在则更新,key不存在则添加
map2 += ("a"->0)
map2.put("aa",1)

println(map2)
// key存在则修改,key不存在则修改
map2("aa") = 2
map2("zz") = 2
println(map2)

println("取值方式======")
// 根据key取出元素 如果key不存在则抛出异常 java.util.NoSuchElementException: key not found: bb
// 所以使用时需要先使用contains方法来判断key是否存在
// println(map2("bb"))

// 使用get(key)方法来取值 如果key存在,就会返回Some(值),然后再次get就可以取到值
// 如果key不存在就会返回None
//Some(1)
println(map2.get("aa"))
// None
println(map2.get("bb"))

// getOrElse()取值 如果key存在则返回值,如果key不存在则返回默认值
println(map2.getOrElse("bb",0))

println("删除元素======")
// 删除元素
map2 -= ("a")
println(map2)

println("遍历元素======")
// 遍历key、value
for((key,value) <- map2){

}

// 遍历key
for(key <- map2.keys){

}

// 遍历value
for(value <- map2.values){

}

// 遍历元组Tuple2
for(value <- map2){
println(value._1+"---"+value._2)
}

创建Map

可以使用->来进行k-v映射,也可以使用对偶元组

1
2
3
4
// k-v映射
val map = Map("张三" -> 10,"李四" -> 20)
// 采用对偶元组
val map3 = Map(("aaa",1),("bbb",2))

添加或修改

Map的添加操作和修改操作是一样的,如果key存在则更新,如果key不存在则添加

可以使用+=来进行添加或修改元素

1
2
// key存在则更新,key不存在则添加
map2 += ("a"->0)

也可以使用put方法

1
map2.put("aa",1)

也可以通过key来直接赋值

1
map2("aa") = 2

取值

取值都是根据key来进行获取的,有三种方式

可以直接根据key来获取,不过这种方式存在风险,根据key取出元素 如果key不存在则抛出异常 java.util.NoSuchElementException: key not found: bb,所以使用时需要先使用contains方法来判断key是否存在

1
2
3
4
5
6
map2("bb")

// 正确操作
if(map2.contains("bb")){
map2.get("bb")
}

可以使用get方法来获取,使用get(key)方法来取值,如果key存在,就会返回Some(值),然后再次get就可以取到值,如果key不存在就会返回None,如果是None时再进行get操作就会抛出异常java.util.NoSuchElementException: None.get

1
2
3
4
5
6
7
8
// 此时取到的是Some或者None,需要再次进行get操作
map2.get("aa")

// 正确操作
val option = map2.get("aa")
if(!option.eq(None)){
println(option.get)
}

使用getOrElse方法来获取值,如果不存在则返回默认值

1
map2.getOrElse("bb",0)

删除

删除元素也有两种方式

可以使用-=来删除元素

1
map2 -= ("a")

也可以使用remove方法来删除

1
map2.remove("aa")

遍历

map的遍历多种多样,可以遍历key,可以遍历value,也可以遍历key、value,还可以遍历元组

遍历key

1
2
3
4
// 遍历key
for(key <- map2.keys){

}

遍历value

1
2
3
4
// 遍历value
for(value <- map2.values){

}

遍历key、value

1
2
3
4
// 遍历key、value
for((key,value) <- map2){

}

遍历元组

1
2
3
4
// 遍历元组Tuple2
for(value <- map2){
println(value._1+"---"+value._2)
}

集Set

Set是不重复的元素集合,无序,有可变Set(scala.collection.mutable.Set)和不可变Set(scala.collection.immutable.Set),默认是不可变的Set

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
println("创建Set========")
// 创建不可变的Set
val set = Set(1,2,1)
println(set)

// 创建可变的Set,需要引包
val set1 = mutable.Set(12,23,34,12)
println(set1)

println("添加元素========")
// 添加元素有三种方式
set1.add(11)
set1 += 13
set1 += (14)
println(set1)

println("删除元素========")
// 对应于添加元素的三种方式,删除元素也同样有三种方式
set1.remove(11)
set1 -= 13
set1 -= (14)
println(set1)

println("遍历元素=======")
for(item <- set1){
println(item)
}

添加元素

set添加元素有三种方式

可以使用add方法添加元素

1
set1.add(11)

也可以使用+=来添加元素

1
set1 += 13

+=也可以同时添加多个元素

1
set1 += (14,15)

删除元素

与添加元素相同,对应的也有三种删除元素的操作方式

使用remove方法删除元素

1
set1.remove(11)

使用-=删除元素

1
set1 -= 13

同样-=也支持删除多个元素

1
set1 -= (14,15)

欢迎关注我的其它发布渠道