Introduction
One variable holds one value — but real data comes in crowds: 40 students, 200 products, a whole class's marks. Dart gives you three collections for crowds, and each has a personality: the List keeps items in order, the Set refuses duplicates, and the Map stores every value under a name (a key) so you can fetch it instantly. Almost every app screen you will ever build shows data from one of these three. (Roman Urdu: List = tartib wali line, Set = duplicate-mukt dabba, Map = naam ke sath value.)
Key points
- A
Listis an ordered row of values of one type:List<String> names = ['Ali', 'Sara'];. You reach an item by its index — and counting starts at 0, so the first item isnames[0], the second isnames[1]. - List tools you will use daily:
length(how many),add(x)(one more at the end),remove(x)(take this value out),contains(x)(is it here? true/false). A list pairs perfectly with thefor-inloop from Lesson D.5.(Roman Urdu: List mein ginti 0 se shuru hoti hai — pehli cheez hamesha [0] hai.) - A
Setis written with{ }and keeps every value only once:{5, 12, 5}quietly becomes{5, 12}. There is no order promise and no index — a Set answers questions likecontains, it does not line items up. - A
Mapstores key → value pairs:Map<String, int> marks = {'Ali': 92};. Fetch by key:marks['Ali']gives 92. Add or change a pair with the same move:marks['Bilal'] = 78;. - A Map lookup for a missing key gives
null— not a crash, not zero:null, meaning "nothing here". That is your first meeting with null; Lesson D.9 is fully about handling it safely (for example with??). - Which one do I pick? Order matters and duplicates are fine → List. Duplicates must be impossible → Set. Every value needs a name or ID to fetch it by → Map.
Code examples
Example 1 — The List: order, index, add, remove
void main() {
List<String> students = ['Ali', 'Sara', 'Bilal'];
print(students.length); // 3
print(students[0]); // Ali — ginti 0 se shuru
print(students[2]); // Bilal
students.add('Zara');
students.remove('Bilal');
print(students); // [Ali, Sara, Zara]
}What it does: The list starts with three names. Index 0 fetches the first, index 2 the third. add puts Zara at the end, remove takes Bilal out by value, and printing the list itself shows the whole row.
What you will see: five lines — 3, Ali, Bilal, and finally [Ali, Sara, Zara]. If you try students[3] before adding Zara, Dart throws a RangeError: index 3 does not exist in a 3-item list whose last index is 2. Index mistakes are the most common collection bug — always think "last index = length − 1".
Example 2 — The Set: duplicates quietly disappear
void main() {
Set<int> rollNumbers = {5, 12, 5, 9, 12};
print(rollNumbers); // {5, 12, 9} — duplicate gayab
print(rollNumbers.contains(9)); // true
print(rollNumbers.contains(7)); // false
rollNumbers.add(20);
print(rollNumbers.length); // 4
}What it does: You wrote five numbers, but the Set kept only the three different ones — the second 5 and second 12 were refused silently. contains answers membership questions, and add grows the set with a genuinely new value.
What you will see: four lines — {5, 12, 9}, true, false, 4. Use a Set whenever "the same thing twice" would be a bug: roll numbers, usernames, booked seat numbers.
Example 3 — The Map: every value has a name
void main() {
Map<String, int> marks = {
'Ali': 92,
'Sara': 85,
};
print(marks['Ali']); // 92
marks['Bilal'] = 78; // naya pair add
print(marks.length); // 3
int? zaraMarks = marks['Zara'];
print(zaraMarks ?? 'Not found'); // Not found
}What it does: Keys are names, values are marks. marks['Ali'] fetches by name — no counting, no index. Writing marks['Bilal'] = 78 adds a brand-new pair. The last part asks for Zara, who is not in the map: the lookup gives null, the variable is typed int? (it is allowed to be empty — D.9 explains), and ?? prints 'Not found' instead of the null.
What you will see: three lines — 92, 3, Not found. A list of maps like this — one map per student — is exactly the data shape behind the Flutter project in Lesson F.5.
Quick recap
- List: ordered, index from 0, duplicates allowed —
add,remove,length,contains. - Set:
{ }, every value kept once, no index — perfect for "no duplicates" data. - Map: key → value pairs, fetch by name —
marks['Ali']. Missing key →null. - Last index of a list =
length - 1. Most collection bugs live right there.
Common mistakes
- Counting list items from 1 —
students[1]is the second student. Dart, like almost every language, counts from 0. When the wrong name prints, check the index first. - Expecting a Set to keep order or duplicates — a Set makes no order promise and drops repeats on purpose. If order or repeats matter to you, you wanted a List.
- Trusting a Map lookup blindly —
marks['Zara']isnullwhen Zara is absent, and printing or calculating with that null surprises beginners. Always decide what happens when the key is missing: check it, or give a fallback with??.
Practice
- Make a list of 5 fruit names. Print the first and the last (use
length - 1for the last index), add one more fruit, remove one, and print the final list. - Build a
Map<String, String>of 4 friends with their cities. Print one friend's city by key, then look up a name that is not in the map and print a friendly fallback message using??.