Dart Set
最后修改于 2025 年 4 月 4 日
在 Dart 中,Set 是一个包含唯一元素的集合。它不允许重复值,并提供高效的成员资格测试操作。
Set 实现了 Iterable 接口,并提供了像 union(并集)、intersection(交集)和 difference(差集)这样的数学集合操作方法。元素必须具有一致的 Object.== 和 Object.hashCode 实现。
创建集合
创建 Set 最简单的方法是使用 Set 构造函数或字面量语法。
void main() {
// Using constructor
var numbers = Set<int>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
// Using literal
var colors = {'red', 'green', 'blue'};
print(numbers);
print(colors);
}
我们创建了两个 Set:一个使用构造函数,另一个使用字面量语法。泛型类型指定了元素的类型。重复项会被自动删除。
$ dart main.dart
{1, 2, 3}
{red, green, blue}
基本 Set 操作
Set 提供了添加、删除和检查元素的方法。
void main() {
var fruits = {'apple', 'banana', 'orange'};
// Add elements
fruits.add('pear');
fruits.addAll(['kiwi', 'mango']);
// Check elements
print(fruits.contains('apple')); // true
print(fruits.contains('grape')); // false
// Remove elements
fruits.remove('banana');
fruits.removeWhere((fruit) => fruit.startsWith('m'));
print(fruits);
}
我们演示了基本的 Set 操作。addAll 用于添加多个元素,而 removeWhere 用于删除满足条件的元素。contains 用于检查成员资格。
$ dart main.dart
true
false
{apple, orange, pear, kiwi}
集合操作
Set 支持并集、交集和差集等数学运算。
void main() {
var set1 = {1, 2, 3, 4, 5};
var set2 = {4, 5, 6, 7, 8};
// Union
print(set1.union(set2));
// Intersection
print(set1.intersection(set2));
// Difference
print(set1.difference(set2));
// Check subset
print(set1.containsAll({2, 3})); // true
}
这些操作会创建新的 Set,而不会修改原始 Set。union 用于合并元素,intersection 用于查找共同元素,difference 用于查找 set1 中不包含在 set2 中的元素。
$ dart main.dart
{1, 2, 3, 4, 5, 6, 7, 8}
{4, 5}
{1, 2, 3}
true
遍历 Set
由于 Set 实现了 Iterable,因此可以使用多种方法进行遍历。
void main() {
var languages = {'Dart', 'Python', 'Java', 'Go', 'Rust'};
// for-in loop
for (var lang in languages) {
print(lang);
}
// forEach method
languages.forEach((lang) => print(lang.toUpperCase()));
// map and where
var shortNames = languages.where((lang) => lang.length <= 4);
print(shortNames);
}
我们演示了三种处理 Set 元素的方法。遍历顺序是不指定的,但在单个程序运行中是一致的。
$ dart main.dart
Dart
Python
Java
Go
Rust
DART
PYTHON
JAVA
GO
RUST
{Dart, Java, Go}
包含自定义对象的 Set
在 Set 中使用自定义对象时,需要正确实现 == 和 hashCode。
class Book {
final String title;
final String author;
Book(this.title, this.author);
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is Book && title == other.title && author == other.author;
@override
int get hashCode => title.hashCode ^ author.hashCode;
}
void main() {
var library = Set<Book>();
var book1 = Book('Dart in Action', 'Manning');
var book2 = Book('Flutter Cookbook', 'Packt');
var book3 = Book('Dart in Action', 'Manning'); // Same as book1
library.add(book1);
library.add(book2);
library.add(book3);
print(library);
print('book1 and book3 same: ${library.contains(book3)}');
}
Book 类实现了 == 和 hashCode 来确保逻辑相等性。尽管 book1 和 book3 是不同的实例,但它们被认为是相等的,因此只有一个会被添加到 Set 中。
$ dart main.dart
{Book(Dart in Action, Manning), Book(Flutter Cookbook, Packt)}
book1 and book3 same: true
最佳实践
- 元素唯一性:确保元素具有正确的 == 和 hashCode 实现。
- 性能:当需要快速的 contains 检查时,请使用 Set。
- 不可变性:考虑为不可变数据使用 const Set。
- 类型安全:始终指定泛型类型以提高清晰度。
来源
本教程介绍了 Dart 的 Set 接口,并通过实际示例演示了其用于唯一元素集合的关键特性和使用模式。
作者
列出 所有 Dart 教程。