In Dart, there's no dedicated "array" type — ordered collections are represented by the List class. You can use a List to store a collection of items, such as a list of names or a list of numbers.
To create a List in Dart, use the List type and specify the type of elements it holds inside angle brackets (< and >):
List<int> numbers = [1, 2, 3, 4, 5];
This creates a list of integers called numbers with the elements 1, 2, 3, 4, and 5.
A note on the new keyword: new has been optional since Dart 2, and as of Dart 3 the bare List<String>() generative constructor no longer exists at all — calling it is a compile error. To create an empty, growable list, use an empty list literal or one of the named constructors:
// Preferred: empty growable list literal
List<String> names = <String>[];
// Equivalent alternatives
List<String> names2 = List<String>.empty(growable: true);
// A fixed-length list pre-filled with a value
List<String> placeholders = List<String>.filled(3, 'placeholder');
Lists have many useful methods for adding, removing, and manipulating elements.
We'll use the following lists to demonstrate the core List methods in Dart:
List<int> numbers = [1, 2, 3, 4, 5];
List<Object> mixed = [1, '2', 3.0, true, [4, 5]];
- add(element): Adds an element to the end of the list.
numbers.add(6); // [1, 2, 3, 4, 5, 6]
- addAll(elements): Adds all the elements of an iterable to the end of the list.
numbers.addAll([7, 8, 9]); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
- clear(): Removes all elements from the list.
numbers.clear(); // []
- remove(element): Removes the first occurrence of an element from the list.
numbers.remove(3); // [1, 2, 4, 5, 6, 7, 8, 9]
- removeAt(index): Removes the element at a specific index from the list.
numbers.removeAt(2); // [1, 2, 5, 6, 7, 8, 9]
- removeLast(): Removes the last element from the list.
numbers.removeLast(); // [1, 2, 5, 6, 7, 8]
- removeRange(start, end): Removes a range of elements from the list.
numbers.removeRange(1, 3); // [1, 8]
- insert(index, element): Inserts an element at a specific index in the list.
numbers.insert(1, 2); // [1, 2, 8]
- insertAll(index, elements): Inserts all the elements of an iterable at a specific index in the list.
numbers.insertAll(1, [3, 4, 5]); // [1, 3, 4, 5, 2, 8]
- sort([compare]): Sorts the elements in the list according to the provided comparator function.
numbers.sort(); // [1, 2, 3, 4, 5, 8]
- indexOf(element): Returns the index of the first occurrence of an element in the list, or -1 if not found.
int index = numbers.indexOf(4); // 3
- lastIndexOf(element): Returns the index of the last occurrence of an element in the list, or -1 if not found.
int lastIndex = numbers.lastIndexOf(4); // 3
- sublist(start, [end]): Returns a new list containing the elements in a range of the list.
List<int> sublist = numbers.sublist(1, 3); // [2, 3]
- asMap(): Returns a new map view of the list, keyed by index.
Map<int, int> map = numbers.asMap(); // {0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 8}
- forEach(function): Calls the provided function on each element in the list.
numbers.forEach((element) {
print(element);
});
-
fold(initialValue, combine): Reduces the list to a single value by repeatedly calling the combine function on the elements, starting with
initialValue.
int sum = numbers.fold(0, (prev, element) => prev + element); // 15
-
List.generate(count, generator): Creates a new list where the elements are produced by calling the generator function
counttimes.
// Create a list of 10 random numbers
final random = Random(); // no `new` needed
List<int> randomNumbers = List.generate(10, (_) => random.nextInt(100));
-
any(test): Returns
trueif at least one element of the list satisfies the provided test function.
bool anyGreaterThanFour = numbers.any((element) => element > 4); // true
-
contains(element): Returns
trueif the list contains the specified element.
bool containsThree = numbers.contains(3); // true
- elementAt(index): Returns the element at the specified index in the list.
int elementAtIndexTwo = numbers.elementAt(2); // 3
-
every(test): Returns
trueif every element of the list satisfies the provided test function.
bool allGreaterThanZero = numbers.every((element) => element > 0); // true
- expand(function): Returns a new list where each element is replaced by the elements returned by the function.
List<int> expanded = numbers.expand((element) => [element, element * 2]).toList();
// [1, 2, 2, 4, 3, 6, 4, 8, 5, 10]
- fillRange(start, end, [fillValue]): Sets the elements in a range of the list to a specified value.
numbers.fillRange(2, 5, 0); // [1, 2, 0, 0, 0]
-
firstWhere(test, {orElse}): Returns the first element that satisfies the test function. With null safety,
orElsemust return a value of the list's element type (or you can omit it and let it throw if nothing matches).
int firstGreaterThanTwo = numbers.firstWhere(
(element) => element > 2,
orElse: () => -1,
); // 3
-
cast<T>(): Returns a view of the list with element type
T. This doesn't filter elements — it's a lazy view, and accessing an element that isn't actually of typeTthrows at runtime. It's meant for narrowing a list you already know is uniformly typed, not for picking elements out of a mixed list (usewhereType<T>()for that).
List<num> nums = [1, 2, 3];
List<int> ints = nums.cast<int>().toList(); // [1, 2, 3]
- followedBy(other): Returns a new iterable containing the elements of the current list followed by the elements of another iterable.
List<int> combined = numbers.followedBy([100, 200]).toList();
- join([separator]): Concatenates the elements in the list into a single string, with an optional separator between each element.
String joined = mixed.join(', '); // '1, 2, 3.0, true, [4, 5]'
- lastWhere(test, {orElse}): Returns the last element that satisfies the test function.
Object lastBool = mixed.lastWhere(
(element) => element is bool,
orElse: () => false,
); // true
- map(function): Returns a new iterable where each element is the result of calling the function on the corresponding element of the original list.
List<int> multiplied = numbers.map((element) => element * 2).toList(); // [2, 4, 6, 8, 10]
-
reduce(combine): Reduces the list to a single value by repeatedly calling the combine function on the elements of the list. Unlike
fold, there's no initial value — the first element is used as the starting point, so the list can't be empty.
int sum = numbers.reduce((value, element) => value + element); // 15
-
singleWhere(test, {orElse}): Returns the only element that satisfies the test function, or throws/falls back to
orElseif there isn't exactly one match.
Object singleString = mixed.singleWhere(
(element) => element is String,
orElse: () => 'none found',
); // '2'
-
skip(count): Returns a new iterable that skips the first
countelements of the original list.
List<Object> skipped = mixed.skip(2).toList(); // [3.0, true, [4, 5]]
- skipWhile(test): Returns a new iterable that skips elements from the original list while they satisfy the test function.
List<Object> skippedWhile = mixed.skipWhile((element) => element is! bool).toList();
// [true, [4, 5]]
-
take(count): Returns a new iterable containing the first
countelements of the original list.
List<Object> taken = mixed.take(3).toList(); // [1, '2', 3.0]
- takeWhile(test): Returns a new iterable containing elements from the original list while they satisfy the test function.
List<Object> takenWhile = mixed.takeWhile((element) => element is! bool).toList();
// [1, '2', 3.0]
- toList(): Returns a new growable list with the elements of the original iterable.
List<Object> list = mixed.toList(); // [1, '2', 3.0, true, [4, 5]]
- toSet(): Returns a new set with the elements of the original list.
Set<Object> set = mixed.toSet(); // {1, '2', 3.0, true, [4, 5]}
- toString(): Returns a string representation of the list.
String stringified = mixed.toString(); // '[1, 2, 3.0, true, [4, 5]]'
- where(test): Returns a new iterable containing only the elements of the original list that satisfy the test function.
List<Object> whereBool = mixed.where((element) => element is bool).toList(); // [true]
-
whereType<T>(): Returns a new iterable containing only the elements of the original list that are of type
T.
List<double> whereDouble = mixed.whereType<double>().toList(); // [3.0]
Modern Dart 3 list features
A few language features that have landed since the methods above were first popular, and that make day-to-day list work nicer:
-
Spread operator (
.../...?): inline one list's elements into another.
List<int> a = [1, 2, 3];
List<int> b = [0, ...a, 4]; // [0, 1, 2, 3, 4]
-
Collection
ifandfor: build lists conditionally or iteratively without a separate loop.
bool includeZero = true;
List<int> c = [
if (includeZero) 0,
for (var n in a) n * n,
]; // [0, 1, 4, 9]
-
Null-aware elements (Dart 3.8+): skip an element automatically if it evaluates to
null.
int? maybeValue = getValue(); // could be null
List<int> d = [1, 2, ?maybeValue, 3];
- List patterns (Dart 3 pattern matching): destructure lists directly.
var [first, second, ...rest] = numbers;
print('$first, $second, $rest');
- Unmodifiable / const lists: prefer these when a list shouldn't change after creation.
const List<int> fixed = [1, 2, 3];
List<int> readOnlyView = List.unmodifiable([1, 2, 3]);
Top comments (2)
Can't even create unnamed constructor like that for a list. Needs updation
I updated it. Thank you