Collections
Apex has three collection types.
Apex has three collection types. They are generic (List<T>, Set<T>, Map<K, V>), can nest, and can hold primitives, sObjects, or user-defined types.
Yes (index from 0) list[i], get(i) Query results, DML batches
No (iteration order is insertion order in practice, but do not rely on it) Unique IDs, membership tests Lookups by ID or key
6.1 List
List<String> colors = new List<String>{ 'red', 'green' };
colors.add('blue');
colors.add(0, 'black'); // insert at index
String first = colors[0]; // 'black'
Integer n = colors.size(); // 4
Boolean has = colors.contains('red'); // true
Integer idx = colors.indexOf('green');
colors.remove(1); // remove by index
colors.sort(); // natural ascending sort
List<String> copy = colors.clone();
colors.addAll(new List<String>{ 'cyan', 'magenta' });
Boolean empty = colors.isEmpty();
colors.clear();
String[] arr = new String[3]; // array syntax is the same as List<String>
List<Account> accs = [SELECT Id, Name FROM Account LIMIT 10];6.2 Set
Strings in sets and map keys are case-sensitive: 'Acme' and 'acme' are different keys. Normalize with toLowerCase() when needed.
Set<Id> accountIds = new Set<Id>();
for (Contact c : [SELECT AccountId FROM Contact WHERE AccountId != null LIMIT 200]) {
accountIds.add(c.AccountId); // duplicates ignored
}
Set<String> a = new Set<String>{ 'x', 'y', 'z' };
Set<String> b = new Set<String>{ 'y', 'z', 'w' };
Set<String> union = a.clone(); union.addAll(b); // x y z w
Set<String> inter = a.clone(); inter.retainAll(b); // y z
Set<String> diff = a.clone(); diff.removeAll(b); // x
Boolean containsAll = a.containsAll(new Set<String>{ 'x', 'y' });6.3 Map
Map<String, Integer> stock = new Map<String, Integer>{ 'apple' => 10, 'pear' => 4 };
stock.put('plum', 7);
Integer apples = stock.get('apple'); // 10
Integer none = stock.get('kiwi'); // null (no exception)
Boolean hasPear = stock.containsKey('pear');
Set<String> keys = stock.keySet();
List<Integer> values = stock.values();
stock.remove('pear');
for (String fruit : stock.keySet()) {
System.debug(fruit + ' → ' + stock.get(fruit));
}
// the most useful idiom in Apex: build a Map<Id, SObject> directly from a query
Map<Id, Account> accountsById = new Map<Id, Account>(
[SELECT Id, Name FROM Account WHERE Industry = 'Technology']
);
Set<Id> ids = accountsById.keySet();6.4 Grouping with maps of lists
Map<Id, List<Contact>> contactsByAccount = new Map<Id, List<Contact>>();
for (Contact c : [SELECT Id, AccountId, LastName FROM Contact WHERE AccountId != null]) {
if (!contactsByAccount.containsKey(c.AccountId)) {
contactsByAccount.put(c.AccountId, new List<Contact>());
}
contactsByAccount.get(c.AccountId).add(c);
}6.5 Sorting custom types
Since Winter '24 you can also pass a System.Comparator<T> to List.sort() to sort the same type in different ways (§38).
public class Employee implements Comparable {
public String name;
public Decimal salary;
public Employee(String n, Decimal s) { name = n; salary = s; }
public Integer compareTo(Object other) {
Employee o = (Employee) other;
if (salary == o.salary) return 0;
return salary > o.salary ? -1 : 1; // descending by salary
}
}
List<Employee> staff = new List<Employee>{ new Employee('A', 50), new Employee('B', 90) };
staff.sort();