Lesson 21 min
List Mastery — Methods & Operations
00:00 / 00:00
List Mastery — Methods & Operations
A List in Dart is an ordered collection of items. It is one of the most commonly used data structures, equivalent to arrays in other languages — but far more powerful.
1. Creating Lists
Literal Syntax — []
dartvoid main() { // Typed list List<int> numbers = [1, 2, 3, 4, 5]; List<String> names = ['Amit', 'Priya', 'Rahul']; List<bool> flags = [true, false, true]; // Type inferred by Dart var colors = ['red', 'green', 'blue']; // List<String> // Empty list List<double> prices = []; var items = <String>[]; }
List.filled() — Fixed Size with Default Value
Creates a list of a specific size, with every element set to a default value.
dartvoid main() { // 5 zeros var zeros = List.filled(5, 0); print(zeros); // [0, 0, 0, 0, 0] // 3 empty strings var blanks = List.filled(3, ''); print(blanks); // ['', '', ''] }
List.generate() — Generate Elements Programmatically
dartvoid main() { // Generate squares: [0, 1, 4, 9, 16] var squares = List.generate(5, (i) => i * i); print(squares); // [0, 1, 4, 9, 16] // Generate a list of labels var labels = List.generate(4, (i) => 'Item ${i + 1}'); print(labels); // [Item 1, Item 2, Item 3, Item 4] // Generate even numbers var evens = List.generate(5, (i) => i * 2); print(evens); // [0, 2, 4, 6, 8] }
Growable vs Fixed-Length Lists
dartvoid main() { // Growable (default) — you can add/remove elements var growable = [1, 2, 3]; growable.add(4); // OK // Fixed-length — size cannot change var fixed = List.filled(3, 0, growable: false); // fixed.add(4); // ERROR: Cannot add to a fixed-length list // Fixed lists still allow value changes fixed[0] = 99; print(fixed); // [99, 0, 0] }
2. Accessing Elements
dartvoid main() { List<String> fruits = ['mango', 'apple', 'banana', 'grape', 'orange']; // By index (0-based) print(fruits[0]); // mango print(fruits[2]); // banana // .first and .last print(fruits.first); // mango print(fruits.last); // orange // .elementAt() — same as [] but method syntax print(fruits.elementAt(3)); // grape // .length print(fruits.length); // 5 // Check if empty print(fruits.isEmpty); // false print(fruits.isNotEmpty); // true }
3. Adding Elements
dartvoid main() { List<String> cart = ['Laptop']; // add() — single element at the end cart.add('Mouse'); print(cart); // [Laptop, Mouse] // addAll() — multiple elements at the end cart.addAll(['Keyboard', 'Monitor']); print(cart); // [Laptop, Mouse, Keyboard, Monitor] // insert() — at specific index cart.insert(1, 'Mousepad'); print(cart); // [Laptop, Mousepad, Mouse, Keyboard, Monitor] // insertAll() — multiple at specific index cart.insertAll(0, ['USB Hub', 'Webcam']); print(cart); // [USB Hub, Webcam, Laptop, Mousepad, Mouse, Keyboard, Monitor] }
4. Removing Elements
dartvoid main() { List<int> numbers = [1, 2, 3, 4, 5, 2, 6]; // remove() — removes FIRST occurrence of the value numbers.remove(2); print(numbers); // [1, 3, 4, 5, 2, 6] // removeAt() — removes at specific index numbers.removeAt(0); print(numbers); // [3, 4, 5, 2, 6] // removeLast() — removes the last element numbers.removeLast(); print(numbers); // [3, 4, 5, 2] // removeWhere() — removes all elements matching a condition numbers.removeWhere((n) => n % 2 == 0); print(numbers); // [3, 5] // clear() — removes all elements numbers.clear(); print(numbers); // [] }
5. Searching & Checking
dartvoid main() { List<String> cities = ['Mumbai', 'Delhi', 'Pune', 'Bangalore', 'Pune']; // contains() — true/false print(cities.contains('Pune')); // true print(cities.contains('Chennai')); // false // indexOf() — first occurrence index (-1 if not found) print(cities.indexOf('Pune')); // 2 print(cities.indexOf('Chennai')); // -1 // lastIndexOf() — last occurrence print(cities.lastIndexOf('Pune')); // 4 // indexWhere() — find index by condition int idx = cities.indexWhere((city) => city.startsWith('B')); print(idx); // 3 (Bangalore) // any / every (HOF-style) print(cities.any((c) => c.length > 8)); // true (Bangalore) print(cities.every((c) => c.length > 3)); // true }
6. Sorting
dartvoid main() { List<int> scores = [78, 45, 92, 61, 88]; // Default sort (ascending) scores.sort(); print(scores); // [45, 61, 78, 88, 92] // Custom sort — descending scores.sort((a, b) => b.compareTo(a)); print(scores); // [92, 88, 78, 61, 45] List<String> names = ['Zara', 'Amit', 'Priya', 'Karan']; // Alphabetical names.sort((a, b) => a.compareTo(b)); print(names); // [Amit, Karan, Priya, Zara] // By length names.sort((a, b) => a.length.compareTo(b.length)); print(names); // [Amit, Zara, Karan, Priya] }
Note: sort() modifies the list in place. To sort without changing the original, copy first: var sorted = [...list]..sort();
7. Slicing with sublist()
dartvoid main() { List<int> numbers = [10, 20, 30, 40, 50, 60, 70]; // sublist(start) — from index to end print(numbers.sublist(3)); // [40, 50, 60, 70] // sublist(start, end) — start inclusive, end exclusive print(numbers.sublist(1, 4)); // [20, 30, 40] // Get first 3 elements print(numbers.sublist(0, 3)); // [10, 20, 30] // Get last 3 elements print(numbers.sublist(numbers.length - 3)); // [50, 60, 70] }
8. Spread Operator with Lists
The ... spread operator lets you expand a list into another:
dartvoid main() { List<int> list1 = [1, 2, 3]; List<int> list2 = [4, 5, 6]; // Combine lists List<int> combined = [...list1, ...list2]; print(combined); // [1, 2, 3, 4, 5, 6] // Insert in the middle List<int> withMiddle = [...list1, 99, 100, ...list2]; print(withMiddle); // [1, 2, 3, 99, 100, 4, 5, 6] // Null-aware spread (...?) List<int>? maybeNull; List<int> safe = [...list1, ...?maybeNull]; print(safe); // [1, 2, 3] // Copy a list (avoids reference sharing) List<int> copy = [...list1]; copy.add(4); print(list1); // [1, 2, 3] — unchanged print(copy); // [1, 2, 3, 4] }
9. List of Lists — 2D Lists
dartvoid main() { // 2D list (matrix) List<List<int>> matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9], ]; // Access element at row 1, col 2 print(matrix[1][2]); // 6 // Print all rows for (var row in matrix) { print(row); } // [1, 2, 3] // [4, 5, 6] // [7, 8, 9] // Generate a 3x3 zero matrix var zeroMatrix = List.generate(3, (_) => List.filled(3, 0)); print(zeroMatrix); // [[0, 0, 0], [0, 0, 0], [0, 0, 0]] }
10. Type Annotations
dartvoid main() { // Explicit type annotations List<int> integers = [1, 2, 3]; List<String> strings = ['a', 'b', 'c']; List<double> doubles = [1.1, 2.2, 3.3]; List<bool> booleans = [true, false, true]; // List of objects (mixed — avoid in practice) List<dynamic> mixed = [1, 'hello', true, 3.14]; // Using var (type inferred) var inferredList = [10, 20, 30]; // Dart infers List<int> }
11. Real Project — Todo List Manager
dartclass Todo { final String id; String title; bool isCompleted; Todo(this.id, this.title, {this.isCompleted = false}); String toString() => '[${ isCompleted ? "✓" : " " }] $title'; } class TodoList { final List<Todo> _todos = []; // Add a new todo void add(String title) { _todos.add(Todo(DateTime.now().toString(), title)); print('Added: "$title"'); } // Mark a todo complete by index void complete(int index) { if (index >= 0 && index < _todos.length) { _todos[index].isCompleted = true; } } // Remove a todo by index void remove(int index) { if (index >= 0 && index < _todos.length) { String removed = _todos[index].title; _todos.removeAt(index); print('Removed: "$removed"'); } } // Clear completed todos void clearCompleted() { _todos.removeWhere((todo) => todo.isCompleted); print('Cleared completed todos.'); } // Get remaining count int get remaining => _todos.where((t) => !t.isCompleted).length; // Print all todos void printAll() { print('\n--- Todo List (${_todos.length} items, $remaining remaining) ---'); for (int i = 0; i < _todos.length; i++) { print(' $i. ${_todos[i]}'); } print('---'); } } void main() { var todoList = TodoList(); todoList.add('Buy groceries'); todoList.add('Study Dart collections'); todoList.add('Exercise for 30 minutes'); todoList.add('Read a chapter of a book'); todoList.printAll(); todoList.complete(0); todoList.complete(2); todoList.printAll(); todoList.clearCompleted(); todoList.printAll(); }
Output:
Added: "Buy groceries"
Added: "Study Dart collections"
Added: "Exercise for 30 minutes"
Added: "Read a chapter of a book"
--- Todo List (4 items, 4 remaining) ---
0. [ ] Buy groceries
1. [ ] Study Dart collections
2. [ ] Exercise for 30 minutes
3. [ ] Read a chapter of a book
---
--- Todo List (4 items, 2 remaining) ---
0. [✓] Buy groceries
1. [ ] Study Dart collections
2. [✓] Exercise for 30 minutes
3. [ ] Read a chapter of a book
---
Cleared completed todos.
--- Todo List (2 items, 2 remaining) ---
0. [ ] Study Dart collections
1. [ ] Read a chapter of a book
---
Summary
| Operation | Method(s) |
|---|---|
| Create | [], List.filled(), List.generate() |
| Access | [index], .first, .last, .elementAt() |
| Add | add(), addAll(), insert(), insertAll() |
| Remove | remove(), removeAt(), removeWhere(), clear() |
| Search | contains(), indexOf(), indexWhere() |
| Sort | sort(), sort((a,b) => ...) |
| Slice | sublist(start, end) |
| Combine | Spread [...list1, ...list2] |
| 2D | List<List<T>> |
Lists are the foundation of data management in Dart and Flutter. Every time you build a list of widgets, manage state, or process API responses — you will be using these operations.