ZetCode

Dart LinkedListEntry

最后修改于 2025 年 6 月 8 日

在 Dart 中,LinkedListEntryLinkedList 中元素的 असतात 基础基类。它提供了双向链表必需的链接结构,可以高效地遍历和修改元素。每个条目都维护着指向其下一个和上一个邻居的引用,确保了链表内顺畅的导航。

与依赖索引访问的标准列表不同,LinkedList 针对快速插入和删除进行了优化,无需元素移位。这使其非常适合需要频繁修改的场景,例如任务调度、撤销-重做功能和缓冲机制。

要使用 LinkedListEntry,开发者必须扩展它来创建自定义条目类型。这允许每个条目存储额外的数据,同时仍然受益于 Dart 的 LinkedList 实现提供的自动列表管理。

LinkedListEntry 的主要特点

通过利用 LinkedListEntry,开发者可以有效地管理动态集合,同时确保快速的修改和可预测的遍历。

基本的 LinkedListEntry 用法

这是一个简单的示例,演示了如何创建和使用自定义的 LinkedListEntry 子类。

main.dart
import 'dart:collection';

class PersonEntry extends LinkedListEntry<PersonEntry> {
  final String name;
  final int age;

  PersonEntry(this.name, this.age);

  @override
  String toString() => '$name ($age)';
}

void main() {
  var list = LinkedList<PersonEntry>();
  var alice = PersonEntry('Alice', 30);
  var bob = PersonEntry('Bob', 25);
  
  list.add(alice);
  list.add(bob);
  
  print(list);
}

我们创建了一个扩展 LinkedListEntry 的 PersonEntry 类。然后我们创建一个 LinkedList 并添加两个条目。列表会保持插入的顺序。

$ dart main.dart
(Alice (30), Bob (25))

访问相邻条目

LinkedListEntry 提供了 nextprevious 属性来遍历列表。

main.dart
import 'dart:collection';

class TaskEntry extends LinkedListEntry<TaskEntry> {
  final String description;
  
  TaskEntry(this.description);
}

void main() {
  var tasks = LinkedList<TaskEntry>();
  var task1 = TaskEntry('Buy milk');
  var task2 = TaskEntry('Walk dog');
  var task3 = TaskEntry('Write code');
  
  tasks.addAll([task1, task2, task3]);
  
  print('First task: ${task1.next?.description}');
  print('Middle task previous: ${task2.previous?.description}');
  print('Middle task next: ${task2.next?.description}');
  print('Last task previous: ${task3.previous?.description}');
}

我们创建了一个任务链表,并演示了如何在条目之间导航。next 和 previous 属性在列表边界处返回 null。

$ dart main.dart
First task: Walk dog
Middle task previous: Buy milk
Middle task next: Write code
Last task previous: Walk dog

从列表中移除条目

可以通过调用条目上的 unlink 方法将其从列表中移除。

main.dart
import 'dart:collection';

class NumberEntry extends LinkedListEntry<NumberEntry> {
  final int value;

  NumberEntry(this.value);

  @override
  String toString() =>
      value.toString();
}

void main() {
  var numbers = LinkedList<NumberEntry>();
  var one = NumberEntry(1);
  var two = NumberEntry(2);
  var three = NumberEntry(3);

  numbers.addAll([one, two, three]);

  print('Before removal: ${numbers.map((e) => e.value).toList()}');

  two.unlink();
  print('After removal: ${numbers.map((e) => e.value).toList()}');
}

我们演示了如何从列表的中间移除一个条目。unlink 方法会移除该条目并更新相邻条目的链接。

$ dart main.dart
Before removal: (1, 2, 3)
After removal: (1, 3)

检查列表成员资格

LinkedListEntry 提供了一个 list 属性来检查一个条目是否在一个列表中。

main.dart
import 'dart:collection';

class CityEntry extends LinkedListEntry<CityEntry> {
  final String name;
  
  CityEntry(this.name);
}

void main() {
  var cities = LinkedList<CityEntry>();
  var ny = CityEntry('New York');
  var la = CityEntry('Los Angeles');
  
  print('Before adding:');
  print('NY in list: ${ny.list != null}');
  print('LA in list: ${la.list != null}');
  
  cities.add(ny);
  cities.add(la);
  
  print('\nAfter adding:');
  print('NY in list: ${ny.list != null}');
  print('LA in list: ${la.list != null}');
  
  ny.unlink();
  
  print('\nAfter removing NY:');
  print('NY in list: ${ny.list != null}');
  print('LA in list: ${la.list != null}');
}

我们使用 list 属性检查列表成员资格。当条目不在任何列表中时,它返回 null;当它在一个列表中时,则返回 LinkedList 实例。

$ dart main.dart
Before adding:
NY in list: false
LA in list: false

After adding:
NY in list: true
LA in list: true

After removing NY:
NY in list: false
LA in list: true

在其他条目之间插入条目

可以使用 insertBefore/After 在现有条目之间插入条目。

main.dart
import 'dart:collection';

class ProductEntry extends LinkedListEntry<ProductEntry> {
  final String name;
  final double price;

  ProductEntry(this.name, this.price);

  @override
  String toString() => '$name: \$$price';
}

void main() {
  var products = LinkedList<ProductEntry>();
  var apple = ProductEntry('Apple', 0.99);
  var banana = ProductEntry('Banana', 1.49);

  products.addAll([apple, banana]);
  print('Original list: ${products.map((e) => e.toString()).toList()}');

  var orange = ProductEntry('Orange', 1.29);
  apple.insertAfter(orange);
  print('After inserting orange: ${products.map((e) => e.toString()).toList()}');

  var grape = ProductEntry('Grape', 2.99);
  banana.insertBefore(grape);
  print('After inserting grape: ${products.map((e) => e.toString()).toList()}');
}

我们演示了如何在列表的特定位置插入条目。插入操作会自动更新列表中的所有必要链接。

$ dart main.dart
Original list: (Apple: $0.99, Banana: $1.49)
After inserting orange: (Apple: $0.99, Orange: $1.29, Banana: $1.49)
After inserting grape: (Apple: $0.99, Orange: $1.29, Grape: $2.99, Banana: $1.49)

最佳实践

来源

Dart LinkedListEntry 文档

本教程通过实用的示例介绍了 Dart 的 LinkedListEntry,演示了其主要特点和用法模式。

作者

我叫 Jan Bodnar,是一位充满热情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。迄今为止,我已撰写了超过 1,400 篇文章和 8 本电子书。我在教授编程方面拥有十多年的经验。

列出 所有 Dart 教程