(一)Set的定义
Set,集合。表示没有重复元素的集合,特点是:唯一,无序。
Set 有可变(mutable)和不可变(immutable)两种类型。不可变 Set 创建后元素不能修改,可变 Set 可对元素进行添加、删除等操作,这两种类型能满足不同场景需求。
(二)Set的代码格式
语法格式 val 变量名 = Set类型
object Main {
def main(args: Array[String]): Unit = {
// 定义一个set
val set1 = Set("apple", "grape", "apple", "pean")
println(set1)
}
}
关键特性
-
自动去重:Set集合不允许重复元素
- 输入:
"apple", "grape", "apple", "pean" - 输出:
"apple", "grape", "pean"(去掉了重复的"apple")
- 输入:
-
无序性:Set不保证元素的顺序(虽然这里看起来有序,但不要依赖顺序)
-
不可变Set:默认创建的Set是不可变的
(三)不可变与可变 Set 的区别
/*
* 可变(mutable).不可变(immutable)
* 可变:自己的内容可以直接修改。可以使用 +=
* 不可变:自己的内容定义好了,就不能添加,不能删除。
* 默认使用的是 不可变的。
*
* Set 它是内置对象,不需要import,可以直接使用。等价于 import scala.collection.immutable.Set
*
*
* */
object set02 {
def main(args: Array[String]): Unit = {
// 分: 可变set, 不可变
// 默认情况下,使用的Set就是不可变的。
// 可变的Set
val set1 = scala.collection.mutable.Set("apple", "grape","apple","pear")
set1 += "banana"
println(set1)
// 不可变的Set
val course = scala.collection.immutable.Set("apple", "banana")
// 根轴: course += "xxxx" // 这行会报错!
var newCourse = course + "pear"
println(newCourse)
}
}
运行结果
Set(banana, apple, grape, pear)
Set(apple, banana, pear)
关键点详解
1. 可变Set (Mutable Set)
val set1 = scala.collection.mutable.Set("apple", "grape","apple","pear")
set1 += "banana"
- 自动去重:虽然输入有重复的"apple",但Set中只保留一个
- 直接修改:使用
+=直接在原集合上添加"banana" - val关键字:虽然set1是val(不可变引用),但指向的集合内容是可变的
2. 不可变Set (Immutable Set)
val course = scala.collection.immutable.Set("apple", "banana")
// course += "xxxx" // 这行会报错!
var newCourse = course + "pear"
- 不可修改:尝试修改course会编译错误
- 创建新集合:
course + "pear"返回一个新的Set - 函数式风格:不改变原集合,而是创建新集合
重要概念澄清
关于默认Set
// 以下两种写法等价:
val setA = Set(1, 2, 3)
val setB = scala.collection.immutable.Set(1, 2, 3)
val vs 可变性
val表示引用不可变(不能指向其他对象)mutable.Set表示集合内容可变- 所以可以用
val声明可变集合,仍然可以修改其内容
使用场景建议
使用可变Set当:
- 需要频繁添加、删除元素
- 在单线程环境下操作
- 性能要求较高
使用不可变Set当:
- 数据基本不变
- 多线程环境
- 函数式编程风格
- 需要保证数据一致性
这段Scala代码详细演示了可变Set和不可变Set的区别和用法。让我为你详细解释:
代码分析
1. 可变Set (Mutable Set)
// 可变的Set
val set1 = scala.collection.mutable.Set("apple", "grape", "apple", "pear")
set1 += "banana" // 直接修改原Set
println(set1)
特点:
- 使用
scala.collection.mutable.Set - 可以直接修改内容(添加、删除元素)
+=操作符直接在原集合上添加元素- 输出结果会包含新添加的"banana"
2. 不可变Set (Immutable Set)
// 不可变的Set
val course = scala.collection.immutable.Set("apple", "banana")
// 错误: course += "xxxx" // 这行会报错!
var newCourse = course + "pear" // 创建新集合
println(newCourse)
特点:
- 使用
scala.collection.immutable.Set - 创建后内容不可修改
- 不能使用
+=直接添加元素 - 使用
+操作符会返回一个新的Set
重要概念总结
默认行为
// 默认就是不可变的Set(等价于 import scala.collection.immutable.Set)
val defaultSet = Set(1, 2, 3)
可变 vs 不可变对比
| 特性 | 可变Set | 不可变Set |
|---|---|---|
| 修改方式 | 直接修改原集合 | 创建新集合 |
| 操作符 | +=, -= | +, - |
| 性能 | 修改操作快 | 修改操作需要复制 |
| 线程安全 | 不安全 | 安全 |
| 包路径 | scala.collection.mutable | scala.collection.immutable |
实际运行结果
// 可变Set输出
Set(banana, apple, grape, pear)
// 不可变Set输出
Set(apple, banana, pear)
使用建议
- 默认使用不可变Set:更安全,函数式编程风格
- 需要频繁修改时:使用可变Set提高性能
- 多线程环境:优先选择不可变Set
(四)Set常见操作
1.添加元素
2.删除元素
3.添加set
4.查询元素是否存在
5.集合操作-并集
6.集合操作-交集
7.集合操作-差集
object set03 {
def main(args: Array[String]): Unit = {
// 可变的Set
val set1 = scala.collection.mutable.Set("apple", "grape", "apple", "pean")
// 1. 添加元素
set1 += "banana"
// 2. 删除元素 grape
set1 -= "grape"
// 3. 查询元素是否存在 contains 它返回一个Bool值
if (set1.contains("apple")) {
println("apple 存在")
}
// 4. 合并Set union 返回一个新的Set
val set2 = scala.collection.mutable.Set("orange")
val set3 = set1.union(set2)
println(set3)
}
}
操作详解
1. 添加元素
set1 += "banana"
- 使用
+=操作符添加元素 - 直接在原集合上修改(因为是可变Set)
- 如果元素已存在,不会重复添加
2. 删除元素
set1 -= "grape"
- 使用
-=操作符删除元素 - 如果元素不存在,操作会被忽略(不会报错)
3. 查询元素
if (set1.contains("apple")) {
println("apple 存在")
}
- 使用
contains方法检查元素是否存在 - 返回布尔值:
true存在,false不存在 - Set的查找操作非常高效(O(1)时间复杂度)
4. 合并Set
val set2 = scala.collection.mutable.Set("orange")
val set3 = set1.union(set2)
- 使用
union方法合并两个Set - 返回一个新的Set(不修改原集合)
- 自动去重重复元素
运行结果分析
假设初始状态:
set1 = Set("apple", "grape", "pean") // 自动去重后的结果
执行过程:
set1 += "banana"→Set("apple", "grape", "pean", "banana")set1 -= "grape"→Set("apple", "pean", "banana")- 检查"apple"存在,输出:"apple 存在"
set1.union(Set("orange"))→Set("apple", "pean", "banana", "orange")
其他常用操作补充
交集 (intersect)
val setA = Set(1, 2, 3)
val setB = Set(2, 3, 4)
val intersection = setA.intersect(setB) // Set(2, 3)
差集 (diff)
val setA = Set(1, 2, 3)
val setB = Set(2, 3, 4)
val difference = setA.diff(setB) // Set(1)
其他方法
set1.size // 获取元素个数
set1.isEmpty // 判断是否为空
set1.nonEmpty // 判断是否非空
set1.foreach(println) // 遍历所有元素