Dart LinkedHashSet
最后修改于 2025 年 4 月 4 日
在 Dart 中,LinkedHashSet 是一个有序集合实现,它维护插入顺序。它通过确保唯一性并保留顺序来结合 Set 和 List 的属性。
LinkedHashSet 实现 Set 接口,并使用带有链表的哈希表。元素必须具有一致的 Object.== 和 Object.hashCode 实现。
创建 LinkedHashSet
创建 LinkedHashSet 的最简单方法是使用构造函数。
import 'dart:collection';
void main() {
var colors = LinkedHashSet<String>();
colors.add('red');
colors.add('green');
colors.add('blue');
colors.add('red'); // Duplicate ignored
print(colors);
}
我们创建一个颜色 LinkedHashSet。泛型类型指定 String 元素。我们使用 add() 添加元素,重复的元素会自动被忽略。
$ dart main.dart
{red, green, blue}
从 Iterable 创建 LinkedHashSet
我们可以使用 LinkedHashSet.from 从现有的 Iterable 创建 LinkedHashSet。
import 'dart:collection';
void main() {
var numbers = [3, 1, 4, 1, 5, 9, 2, 6];
var uniqueNumbers = LinkedHashSet<int>.from(numbers);
print('Original: $numbers');
print('Unique ordered: $uniqueNumbers');
}
这会从一个包含重复项的列表中创建一个 LinkedHashSet。结果集按照首次出现顺序包含唯一的元素。
$ dart main.dart
Original: [3, 1, 4, 1, 5, 9, 2, 6]
Unique ordered: {3, 1, 4, 5, 9, 2, 6}
检查内容
LinkedHashSet 提供了检查元素和集合属性的方法。
import 'dart:collection';
void main() {
var vowels = LinkedHashSet<String>.from(['a', 'e', 'i', 'o', 'u']);
print(vowels.contains('e')); // true
print(vowels.contains('x')); // false
print(vowels.first); // a
print(vowels.last); // u
print(vowels.length); // 5
}
我们检查 LinkedHashSet 的各种属性。first 和 last 属性反映的是插入顺序,而不是字母顺序。
$ dart main.dart true false a u 5
集合操作
LinkedHashSet 支持标准的集合操作,如 union、intersection 和 difference。
import 'dart:collection';
void main() {
var setA = LinkedHashSet<int>.from([1, 2, 3, 4]);
var setB = LinkedHashSet<int>.from([3, 4, 5, 6]);
print('Union: ${setA.union(setB)}');
print('Intersection: ${setA.intersection(setB)}');
print('Difference: ${setA.difference(setB)}');
}
这些操作返回新的集合。union 合并两个集合中的元素,intersection 查找共同元素,difference 显示 setA 中不在 setB 中的元素。
$ dart main.dart
Union: {1, 2, 3, 4, 5, 6}
Intersection: {3, 4}
Difference: {1, 2}
遍历 LinkedHashSet
我们可以一边遍历 LinkedHashSet 元素,一边保持插入顺序。
import 'dart:collection';
void main() {
var planets = LinkedHashSet<String>.from([
'Mercury', 'Venus', 'Earth', 'Mars',
'Jupiter', 'Saturn', 'Uranus', 'Neptune'
]);
print('Forward order:');
for (var planet in planets) {
print(planet);
}
print('\nReversed order:');
for (var planet in planets.toList().reversed) {
print(planet);
}
}
这演示了正向和反向的遍历。反向遍历需要先转换为列表,因为集合没有反向功能。
$ dart main.dart Forward order: Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune Reversed order: Neptune Uranus Saturn Jupiter Mars Earth Venus Mercury
移除元素
LinkedHashSet 提供了在保持顺序的同时删除元素的方法。
import 'dart:collection';
void main() {
var letters = LinkedHashSet<String>.from([
'A', 'B', 'C', 'D', 'E', 'F', 'G'
]);
print('Original: $letters');
letters.remove('C');
print('After remove: $letters');
letters.removeWhere((letter) => letter.codeUnitAt(0) % 2 == 0);
print('After removeWhere: $letters');
letters.clear();
print('After clear: $letters');
}
我们演示了三种删除方法。removeWhere 根据字符码进行过滤,删除 ASCII 值是偶数的字母。
$ dart main.dart
Original: {A, B, C, D, E, F, G}
After remove: {A, B, D, E, F, G}
After removeWhere: {A, D, F}
After clear: {}
带自定义对象的 LinkedHashSet
使用自定义对象时,我们必须正确实现 hashCode 和 ==。
import 'dart:collection';
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;
@override
String toString() => '$title by $author';
}
void main() {
var library = LinkedHashSet<Book>();
var book1 = Book('1984', 'George Orwell');
var book2 = Book('Brave New World', 'Aldous Huxley');
var book3 = Book('1984', 'George Orwell'); // 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 是不同的对象实例,但它们被认为是相同的。
$ dart main.dart
{1984 by George Orwell, Brave New World by Aldous Huxley}
book1 and book3 same: true
最佳实践
- 顺序保留: 当插入顺序很重要时使用。
- 元素唯一性: 确保元素实现正确的 == 和 hashCode。
- 性能: add/contains/remove 操作为 O(1)。
- 内存: 由于需要跟踪顺序,内存占用比 HashSet 多。
来源
本教程通过实际示例介绍了 Dart 的 LinkedHashSet,演示了其关键特性和用法模式。
作者
列出 所有 Dart 教程。