首先看一下整个集合体系结构,这个结构与Java的集合体系非常相似

集合的顶层接口是Iterable,Iterable接口下面还有一些子接口, SetSeqMap
这几个子接口下面有具体的实现类

  • set下面有HashSet、LinkedHashSet、SortedSet等等
  • seq下面有List、Buffer、Range等等
  • Map下面有HashMap、SortedMap、LinkedHashMap等等
  • 其中Buffer下面还有两个常用的,ArrayBuffer、ListBuffer

这是集合中一些常见的实现类

在讲这个集合体系的时候,还会关联讲到ArrayTuple这两个数据结构

集合

Scala中的集合是分成可变不可变两类集合的

  • 其中可变集合就是说,集合的元素可以动态修改
  • 而不可变集合就是说,集合的元素在初始化之后,就无法修改了

可变集合: 在scala.collection.mutable 这个包下面
不可变集合: 在scala.collection.immutable 这个包下面

我们在创建集合的时候,如果不指定具体的包名,默认会使用不可变集合

Set

先来看一下Set,Set代表一个没有重复元素的集合
这个集合的特性和Java中Set集合的特性基本一样
Set集合分为可变的和不可变的集合,默认情况下使用的是不可变集合

Set可以直接使用,并且不需要使用new关键字,来看一下

scala> val s = Set(1,2,3)
s: scala.collection.immutable.Set[Int] = Set(1, 2, 3)

注意:默认情况下直接创建的set集合是一个不可变集合,在这可以看到是在immutable包里面 的,不可变集合中的元素一经初始化,就不能改变了,所以初始化后再向里面添加元素就报错 了。

scala> val s = Set(1,2,3)
s: scala.collection.immutable.Set[Int] = Set(1, 2, 3)scala> s += 4
<console>:9: error: value += is not a member of scala.collection.immutable.Sets += 4 ^

但是注意,我使用s + 4 这种操作是可以的

scala> val s = Set(1,2,3)
s: scala.collection.immutable.Set[Int] = Set(1, 2, 3)scala> s + 4
res33: scala.collection.immutable.Set[Int] = Set(1, 2, 3, 4)

s + 4 返回的是一个新的集合了,相当于在之前的集合的基础上,创建一个新的集合,新的集合包含之前集合的元素和我们新增的4这个元素

如果想要创建一个可变的set集合,可以使用mutable包下面的set集合,显式指定包名

scala> val s = scala.collection.mutable.Set(1,2,3)
s: scala.collection.mutable.Set[Int] = Set(1, 2, 3)scala> s += 4
res34: s.type = Set(1, 2, 3, 4)

Set常用子类有: HashSet、LinkedHashSet、SortedSet

  • HashSet:这个集合的特点是:集合中的元素不重复、无序
  • LinkedHashSet:这个集合的特点是:集合中的元素不重复、有序,它会用一个链表维护插入顺序, 可以保证集合中元素是有序的
  • SortedSet:这个集合的特点是:集合中的元素不重复、有序,它会自动根据元素来进行排序

演示一下:

  • 先看HashSet
    HashSet集合分为可变和不可变之分, immutable 包下面的是不可变的,后期无法新增元素
    在这里可以使用new关键字,也可以不使用,因为HashSet既是class,又是object,但是包名需要指定, 否则无法识别
scala> val s = new scala.collection.mutable.HashSet[Int]()
s: scala.collection.mutable.HashSet[Int] = Set()scala> s +=1
res35: s.type = Set(1)scala> s +=2
res36: s.type = Set(1, 2)scala> s +=5
res38: s.type = Set(1, 5, 2)

如果在创建集合的时候就初始化了元素,则可以省略泛型的定义,集合会自动识别元素的类型

  • 再来看一下LinkedHashSet
    LinkedHashSet只有可变的,没有不可变的
scala> val s = new scala.collection.mutable.LinkedHashSet[Int]()
s: scala.collection.mutable.LinkedHashSet[Int] = Set()scala> s +=1
res42: s.type = Set(1)scala> s +=2
res43: s.type = Set(1, 2)scala> s +=5
res44: s.type = Set(1, 2, 5)
  • 最后来看一下SortedSet
    SortedSet分为可变集合和不可变集合
scala> val s = scala.collection.mutable.SortedSet[String]()
s: scala.collection.mutable.SortedSet[String] = TreeSet()scala> s +=("c")
res45: s.type = TreeSet(c)scala> s +=("a")
res46: s.type = TreeSet(a, c)scala> s +=("b")
res47: s.type = TreeSet(a, b, c)

从这可以看出来SortedSet集合中的元素是按照元素的字典顺序排序的

针对里面这些Set集合,如果想要迭代他们里面的元素,可以使用for循环直接迭代
以SortedSet为例,其它的 Set、HashSet、LinkedHashSet 都是一样的

scala> for(i <- s ) println(i)
a
b
c

List

接下来看一下List,List属于Seq接口的子接口
List代表一个不可变的列表
创建一个list

scala>  val l = List(1, 2, 3, 4)
l: List[Int] = List(1, 2, 3, 4)

针对List有 headtail 以及 :: 这几个操作
先演示一下 head、tail 操作

scala> l.head
res49: Int = 1
scala> l.tail
res51: List[Int] = List(2, 3, 4)
  • head:表示获取List中的第一个元素
  • tail:表示获取List中第一个元素之后的所有元素

那其实head和tail就可以获取list中的所有元素了

通过 :: 操作符,可以将head和tail的结果合并成一个List

scala> l.head :: l.tail
res52: List[Int] = List(1, 2, 3, 4)

针对List中的元素进行迭代和前面讲的Set集合的迭代是一样的

scala> val l = List(1, 2, 3, 4)
l: List[Int] = List(1, 2, 3, 4)
scala> for(i <- l) println(i)
1
2
3
4

在这里List是不可变的列表,在实际工作中使用的时候会很不方便,因为我们很多场景下都是需要向列表中动态添加元素,这个时候该怎么办呢?

Scala还提供的有一个ListBuffer

ListBuffer:可以支持动态增加或者移除元素

scala> val lb = scala.collection.mutable.ListBuffer[Int]()
lb: scala.collection.mutable.ListBuffer[Int] = ListBuffer()scala> lb +=1
res56: lb.type = ListBuffer(1)scala> lb +=2
res57: lb.type = ListBuffer(1, 2)scala> lb +=5
res58: lb.type = ListBuffer(1, 2, 5)scala> lb -=5
res59: lb.type = ListBuffer(1, 2)

ListBuffer也可以直接使用for循环迭代

scala> for(i <- lb) println(i)
1
2

Map

Map是一种可迭代的键值对(key/value)结构

创建一个不可变的Map

scala> val ages = Map("jack"->30,"tom"->25,"jessic"->23)
ages: scala.collection.immutable.Map[String,Int] = Map(jack -> 30, tom -> 25, jessic -> 23)scala> ages("jack")
res100: Int = 30

创建一个可变的Map

scala> val ages = scala.collection.mutable.Map("jack"->30,"tom"->25,"jessic"->23)
ages: scala.collection.mutable.Map[String,Int] = Map(jessic -> 23, jack -> 30, tom -> 25)scala> ages("jack")
res101: Int = 30

还有一种创建Map的简易方式,这种方式创建的是不可变Map

scala> val ages = Map(("jack",30),("tom",25),("jessic"->23))
ages: scala.collection.immutable.Map[String,Int] = Map(jack -> 30, tom -> 25, jessic -> 23)
  • 查询操作
    获取指定key对应的value,如果key不存在,会报错
scala> val ages = scala.collection.mutable.Map(("jack",30),("tom",25),("jessic"->23))
ages: scala.collection.mutable.Map[String,Int] = Map(jessic -> 23, jack -> 30, tom -> 25)scala> val age = ages("jack")
age: Int = 30scala> val age = ages("jack1")
java.util.NoSuchElementException: key not found: jack1

所以在实际工作中这样直接获取不太好,如果遇到了不存在的key程序会报错,导致程序异常退出。 那是不是可以考虑在获取key的值之前,先判断key是否存在
可以使用contains函数检查key是否存在、 使用if-else语句,如果指定的key不存在,则返回一个默认值

scala> val age = if (ages.contains("jack1")) ages("jack1") else 0
age: Int = 0

这样是没问题的,就是写起来有点麻烦了,有没有方便一点的用法呢? map中还有一个getOrElse函数

scala> val age = ages.getOrElse("jack1", 0)
age: Int = 0scala> val age = ages.getOrElse("jack", 0)
age: Int = 30

建议后期从map中获取数据都使用这个 getOrElse 函数

  • 修改
    更新map中的元素
scala> ages("jack") = 31
scala> ages
res104: scala.collection.mutable.Map[String,Int] = Map(jessic -> 23, jack -> 31, tom -> 25)

增加多个元素

scala> ages += ("hehe" -> 35, "haha" -> 40)
res105: ages.type = Map(hehe -> 35, jessic -> 23, jack -> 31, tom -> 25, haha -> 40)

移除元素

scala> ages -= "hehe"
res106: ages.type = Map(jessic -> 23, jack -> 31, tom -> 25, haha -> 40)
  • 遍历
    遍历map的entrySet
scala> for ((key, value) <- ages) println(key + " " + value)
jessic 23
jack 31
tom 25
haha 40

遍历map的key

scala> for (key <- ages.keySet) println(key)
jessic
jack
tom
haha

遍历map的value

scala> for (value <- ages.values) println(value)
23
31
25
40

最后看一下Map的几个子类: HashMapSortedMapLinkedHashMap

  • HashMap:是一个按照key的hash值进行排列存储的map
  • SortedMap:可以自动对Map中的key进行排序【有序的map】
  • LinkedHashMap:可以记住插入的key-value的顺序

HashMap分为可变和不可变的,没有什么特殊之处
在这主要演示一下SortedMap和LinkedHashMap
SortedMap是不可变的

scala> val ages = scala.collection.immutable.SortedMap("b" -> 30, "a" -> 15, "c" -> 25)
ages: scala.collection.immutable.SortedMap[String,Int] = Map(a -> 15, b -> 30, c -> 25)

LinkedHashMap是可变的

scala> val ages = new scala.collection.mutable.LinkedHashMap[String, Int]()
ages: scala.collection.mutable.LinkedHashMap[String,Int] = Map()
scala> ages("b")=30
scala> ages("a")=15
scala> ages("c")=25
scala> ages
res116: scala.collection.mutable.LinkedHashMap[String,Int] = Map(b -> 30, a -> 15, c -> 25)

Array

Scala中Array的含义与Java中的数组类似,长度不可变
由于Scala和Java都是运行在JVM中,双方可以互相调用,因此Scala数组的底层实际上就是Java数组
数组初始化后,长度就固定下来了,而且元素全部根据其类型进行初始化

scala> val a = new Array[Int](10)
a: Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)scala> a(0)
res65: Int = 0scala> a(0)=1scala> a(0)
res67: Int = 1

也可以直接使用Array()创建数组,元素类型自动推断

scala> val a = Array("hello", "world")scala> a(0)
res68: String = helloscala> val a1 = Array("hello", 30)
a1: Array[Any] = Array(hello, 30)

如果想使用一个长度可变的数组,就需要使用到ArrayBuffer了

ArrayBuffer

Scala中ArrayBuffer与Java中的ArrayList类似,长度可变
ArrayBuffer:添加元素、移除元素
如果不想每次都使用全限定名,则可以预先导入ArrayBuffer类

scala> import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.ArrayBuffer
  • 初始化
    使用ArrayBuffer()的方式可以创建一个空的ArrayBuffer
scala> val b = new ArrayBuffer[Int]()
b: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()
  • 添加元素
    使用+=操作符,可以添加一个元素,或者多个元素
    b += 1 或者 b += (2, 3, 4, 5)
scala> b += 1
res69: b.type = ArrayBuffer(1)scala> b += (2, 3, 4, 5)
res70: b.type = ArrayBuffer(1, 2, 3, 4, 5)

使用insert()函数可以在指定位置插入元素,但是这种操作效率很低,因为需要移动指定位置后的所有元素
向3号角标的位置添加一个元素 30

scala> b.insert(3,30)
scala> b
res72: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 30, 4, 5)
  • 移除元素
    使用 remove() 函数可以移除指定位置的元素
scala> b.remove(1)
res73: Int = 2scala> b
res74: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 3, 30, 4, 5)

注意:Array与ArrayBuffer可以互相进行转换

b.toArray:ArrayBuffer转Array
a.toBuffer:Array转ArrayBuffer

数组常见操作

下面看一下针对数据的常见操作

  • 遍历Array和ArrayBuffer的两种方式
    由于Array和ArrayBuffer都是有角标的,所以在迭代数组中元素的时候除了可以使用前面迭代集合的 方式还可以使用角标迭代
scala> val b=ArrayBuffer(1, 2, 3, 4, 5)
b: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4, 5)
scala>  for(i <- b) println(i)
1
2
3
4 5
scala> for(i <- 0 until b.length ) println(b(i))
1
2
3
4
5
  • 求和、求最大值
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 = 15scala> val max = a.max
max: Int = 5
  • 数组排序
scala> scala.util.Sorting.quickSort(a)
a: Array[Int] = Array(1, 2, 3, 4, 5)scala> a
res99: Array[Int] = Array(1, 2, 3, 4, 5)

Tuple

Tuple:称之为元组,它与Array类似,都是不可变的,但与数组不同的是元组可以包含不同类型的元素 Tuple中的元素角标从 1 开始

注意:目前 Scala 支持的元组最大长度为 22 ,对于更大长度可以使用集合或数组

scala> val t = (1, 3.14, "hehe")
t: (Int, Double, String) = (1,3.14,hehe)scala> t._1
res117: Int = 1scala> t._3
res118: String = hehe

总结

前面讲了很多集合体系中的数据结构,有的是可变的,有的是不可变的,有的是既是可变的又是不可变 的,听起来有点乱,在这里我们总结一下:

  • 可变集合: LinkedHashSet、ListBuffer、ArrayBuffer、LinkedHashMap
  • 不可变集合: List、SortedMap
  • 可变+不可变集合: Set、HashSet、SortedSet、Map、HashMap

还有两个编外人员: Array、Tuple

  • Array:长度不可变,里面的元素可变
  • Tuple:长度不可变,里面的元素也不可变

Scala的集合体系相关推荐

  1. Scala 可变集合体系、不可变集合体系 详解

    文章目录 Scala数据结构的特点 1. Scala的集合基本介绍 2. 可变集合和不可变集合举例 不可变集合继承层次--览图 可变集合继承层次--览图 数组-定长数组(声明泛型) 1. 第一种方式定 ...

  2. java 顶层类_Javase之集合体系之(1)集合顶层类Collection与其迭代器知识

    集合体系之集合顶层类Collection与其迭代器知识 集合的由来:Java是一门面向对象语言,而面向对象语言对事物的描述是通过对象体现的,为了方便对多个对象进行操作,就必须把多个对象进行存储,而要存 ...

  3. Java 集合体系详解——List体系有序集合

    引言 面向对象语言对事物的体现必然是以对象的形式,Java工程师为了方便多多个对象的操作,就对对象进行存储,集合就是存储对象的一种方式,他们的底层都是基于不同的数据结构.当然集合和数组一样都是容器,数 ...

  4. Java容器 | 基于源码分析Map集合体系

    一.容器之Map集合 集合体系的源码中,Map中的HashMap的设计堪称最经典,涉及数据结构.编程思想.哈希计算等等,在日常开发中对于一些源码的思想进行参考借鉴还是很有必要的. 基础:元素增查删.容 ...

  5. Java容器 | 基于源码分析List集合体系

    一.容器之List集合 List集合体系应该是日常开发中最常用的API,而且通常是作为面试压轴问题(JVM.集合.并发),集合这块代码的整体设计也是融合很多编程思想,对于程序员来说具有很高的参考和借鉴 ...

  6. Java进阶(七)Set系列集合、Map集合体系

    七.Set系列集合.Map集合体系 需要学会什么? Set系列集合的特点:Set系列集合的特点和底层原理. 集合工具类Collections:快速的对集合进行元素的添加.排序等操作. 综合案例:把Co ...

  7. Java集合体系总结

    一.集合框架 集合是容纳数据的容器,java常用的集合体系图如下.以集合中是否运行重复元素来分,主要有List和Set接口,List集合中可以有重复元素,Set集合集合中的元素不可重复,Iterato ...

  8. scala 数组集合(思维导图,初级必备)

    scala 系列 scala 入门基础 scala 数组集合 scala 143个数组函数大全 scala 函数 scala OOP scala 高级扩展 scala 数组集合 scala 系列 前言 ...

  9. Scala集合体系:可变集合和不可变集合

    不可变集合继承关系图 可变集合继承关系图

最新文章

  1. LeetCode实战:最大子序和
  2. 禁止服务器的协议,Windows 服务器禁用 SSL 2 和 SSL 3 协议
  3. 导致SEO优化排名不理想的三大因素,你踩雷了没?
  4. Python3_实例汇总
  5. Java 12 - Java StringBuffer和StringBuilder类
  6. ASP.NET WebForm echarts初试随笔
  7. 自定义检验注解_多注解自定义参数校验
  8. 约瑟夫问题(vector的使用)
  9. 立镖机器人浙江_立镖现身LogiMAT 2019 彰显中国仓储分拣技术
  10. zabbix分布式监控部署proxy安装
  11. Docker-compose编排微服务顺序启动解决方案
  12. 10.Linux 高性能服务器编程 --- 信号
  13. RHEL4下建立sendmail服务器
  14. JavaScript初级学习笔记(待完成)
  15. 特征选择 | MATLAB实现特征变量相关性系数图和显著性检验
  16. 浏览器自动化(python)
  17. 可视对讲行业洗牌进行时 企业应该何去何从?
  18. 免费开源51单片机个人课程设计--基于stc89c52及红外遥控的测温智能电风扇
  19. 晚安西南-----地破实验
  20. Python出租车GPS数据的路网匹配(TransBigData+leuvenmapmatching)

热门文章

  1. 2023中央民族大学社会工作专硕考研分享
  2. PS内容识别填充让图片闹鬼?新升级消灭乱涂乱画,让你刮目相看
  3. 脚本报错 未结束的字符串常量 可能导致的原因
  4. 功率预测发展趋势之中长期预报
  5. python中的装饰器的使用实战
  6. 过敏婴儿的4大症状 家长要及时发现正确处理很重要
  7. Word键入自动将单双引号修改为弯引号(‘‘或““)
  8. 微软Windows帝国幕后的10大关键人物
  9. python中常见的内置函数_python常用内置函数
  10. python 列表和元组 还有range