ZetCode

Dart DoubleLinkedQueueEntry

last modified October 18, 2026

In this article, we show how to work with DoubleLinkedQueueEntry in Dart. It represents a single element of a DoubleLinkedQueue and is defined in the dart:collection library.

A DoubleLinkedQueue is a doubly linked list. Each node holds one element and links to the previous and the next node. A DoubleLinkedQueueEntry is a handle to such a node. Through the handle we can read or replace the element, step to the neighbouring entries, and insert or remove elements at that exact position in constant time, without searching for an index.

The queue gives out entries with the firstEntry, lastEntry and forEachEntry methods. The entry API is small:

The class has no public constructor; entries are always obtained from a queue. The examples were run with Dart 3.13.

Navigating between entries

The first example gets the first entry of a queue and walks to its neighbours.

main.dart
import 'dart:collection';

void main() {
  var queue = DoubleLinkedQueue<String>();
  queue.add('Apple');
  queue.add('Banana');
  queue.add('Cherry');

  var first = queue.firstEntry()!;
  print('First: ${first.element}');

  var second = first.nextEntry()!;
  print('Second: ${second.element}');

  var back = second.previousEntry()!;
  print('Back to first: ${back.element}');

  print('Before the first: ${first.previousEntry()}');
  print('Same entry: ${identical(first, back)}');
}

The firstEntry method returns null for an empty queue, so its result is nullable; we assert it with ! because the queue has three elements. The value of an entry is available in its element property. The nextEntry and previousEntry methods return entries of the same queue; moving forward and then back gives the very same object. The first entry has no previous entry, so previousEntry returns null.

$ dart main.dart
First: Apple
Second: Banana
Back to first: Apple
Before the first: null
Same entry: true

Inserting elements around an entry

The prepend and append methods insert a new element relative to an existing entry.

main.dart
import 'dart:collection';

void main() {
  var queue = DoubleLinkedQueue<String>();
  queue.addAll(['Apple', 'Cherry']);

  var first = queue.firstEntry()!;

  first.prepend('Apricot');
  first.append('Banana');

  print(queue);
}

We insert Apricot before the entry holding Apple and Banana right after it. No index is involved and the other elements are not moved; only the links of the neighbouring nodes change. Both methods take an element, not an entry, and return nothing.

$ dart main.dart
{Apricot, Apple, Banana, Cherry}

Removing an entry

An entry can remove itself from the queue.

main.dart
import 'dart:collection';

void main() {
  var queue = DoubleLinkedQueue<String>();
  queue.addAll(['Apple', 'Banana', 'Cherry', 'Date']);

  var second = queue.firstEntry()!.nextEntry()!;

  var removed = second.remove();

  print('Removed: $removed');
  print('Queue: $queue');
  print('Next of Apple: ${queue.firstEntry()!.nextEntry()!.element}');
}

The remove method unlinks the entry from the queue and returns the element it held. The neighbours are linked together, so the entry that held Apple now continues with Cherry.

$ dart main.dart
Removed: Banana
Queue: {Apple, Cherry, Date}
Next of Apple: Cherry

Traversing a queue

Following the links, we can traverse the queue in both directions.

main.dart
import 'dart:collection';

void main() {
  var queue = DoubleLinkedQueue<int>();
  queue.addAll([10, 20, 30, 40, 50]);

  print('Forward:');
  var entry = queue.firstEntry();
  while (entry != null) {
    print(entry.element);
    entry = entry.nextEntry();
  }

  print('Backward:');
  entry = queue.lastEntry();
  while (entry != null) {
    print(entry.element);
    entry = entry.previousEntry();
  }
}

The forward loop starts at firstEntry and follows nextEntry until it reaches null. The backward loop starts at lastEntry and follows previousEntry. Because a variable of a nullable type is promoted to a non-nullable one inside the while condition, we can use entry.element directly.

$ dart main.dart
Forward:
10
20
30
40
50
Backward:
50
40
30
20
10

Modifying a queue with forEachEntry

The forEachEntry method calls a function with each entry of the queue. It is the safe way to change elements or remove some of them while iterating.

main.dart
import 'dart:collection';

void main() {
  var queue = DoubleLinkedQueue<int>();
  queue.addAll([1, 2, 3, 4, 5, 6]);

  queue.forEachEntry((entry) {
    if (entry.element.isEven) {
      entry.element *= 10;
    } else if (entry.element == 5) {
      entry.remove();
    }
  });

  print(queue);
}

The element property is assignable, so we multiply the even elements by ten in place. The entry holding the value 5 removes itself during the iteration. This works because the entries are the nodes of the queue and forEachEntry remembers the next node before it calls our function. Removing elements from a queue while iterating it with a for loop would throw a ConcurrentModificationError.

$ dart main.dart
{1, 20, 3, 40, 60}

Moving and swapping elements

Entries make it easy to rearrange elements.

main.dart
import 'dart:collection';

void main() {
  var queue = DoubleLinkedQueue<String>();
  queue.addAll(['A', 'B', 'C', 'D', 'E']);

  // move the middle element to the front
  var middle = queue.firstEntry()!.nextEntry()!.nextEntry()!;
  var value = middle.remove();
  queue.addFirst(value);
  print('Moved to front: $queue');

  // swap the first and the last element in place
  var first = queue.firstEntry()!;
  var last = queue.lastEntry()!;
  var tmp = first.element;
  first.element = last.element;
  last.element = tmp;
  print('Swapped ends: $queue');

  // an entry is detached once it has been removed
  print('Detached: ${middle.nextEntry()}');
}

First we take the third entry out of the queue with remove and put its element at the front with addFirst. Then we swap the elements of the first and last entries by assigning to element; the entries stay in place and only the stored values change. Finally, we ask a removed entry for its neighbour. A removed entry is detached from the queue, and nextEntry returns null for it.

$ dart main.dart
Moved to front: {C, A, B, D, E}
Swapped ends: {E, A, B, D, C}
Detached: null

Best practices

Source

Dart DoubleLinkedQueueEntry documentation

We have shown how to navigate, insert, remove and modify elements of a DoubleLinkedQueue through DoubleLinkedQueueEntry.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Dart tutorials.