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 教程。