Custom Types in Collections: Wrapper Classes
By the end of this lesson, you'll be able to:
- Build a List, Set, or Map of a custom class rather than a primitive type
- Explain what a wrapper class is and why it's used with collections
- Combine several related fields into one object stored inside a collection
Prerequisites: "Choosing List vs Set vs Map"
The limitation of primitive collections
List<String> productNames = new List<String>{'Widget', 'Gadget'};
List<Decimal> productPrices = new List<Decimal>{49.99, 89.99};
List<String> productNames = new List<String>{'Widget', 'Gadget'};— one list.List<Decimal> productPrices = new List<Decimal>{49.99, 89.99};— a second, separate list kept in sync by position only — fragile, since sorting or filtering one list without the other would silently misalignproductNames[0]with the wrong price. Nothing enforces that these two lists stay related.
A wrapper class holds related data together
public class ProductSummary {
public String name;
public Decimal price;
public ProductSummary(String name, Decimal price) {
this.name = name;
this.price = price;
}
}
List<ProductSummary> products = new List<ProductSummary>{
new ProductSummary('Widget', 49.99),
new ProductSummary('Gadget', 89.99)
};
for (ProductSummary p : products) {
System.debug(p.name + ': R' + p.price);
}
public class ProductSummary {— this is exactly Module 10's class-and-object pattern, now storing custom objects inside aList.public String name;— one field.public Decimal price;— another, permanently paired with the name on the same object.- (blank line)
public ProductSummary(String name, Decimal price) {— the constructor.this.name = name;— sets the name.this.price = price;— sets the price.}— closes the constructor.}— closes the class.- (blank line)
List<ProductSummary> products = new List<ProductSummary>{— a list of wrapper objects, not primitives.new ProductSummary('Widget', 49.99),— one product, name and price together.new ProductSummary('Gadget', 89.99)— a second.};— closes the list literal.- (blank line)
for (ProductSummary p : products) {— loops over the wrapper objects.System.debug(p.name + ': R' + p.price);— no risk of two separate lists drifting out of sync — each object carries its own data.}— closes the loop.
A real business example: Support Ticket Dashboard
public class TicketSummary {
public String subject;
public String priority;
public Integer daysOpen;
public TicketSummary(String subject, String priority, Integer daysOpen) {
this.subject = subject;
this.priority = priority;
this.daysOpen = daysOpen;
}
}
List<TicketSummary> openTickets = new List<TicketSummary>{
new TicketSummary('Login failure', 'High', 2),
new TicketSummary('Slow report load', 'Medium', 5)
};
public class TicketSummary {— a wrapper class with three related fields.public String subject;— the ticket subject.public String priority;— its priority.public Integer daysOpen;— how long it's been open.- (blank line)
public TicketSummary(String subject, String priority, Integer daysOpen) {— the constructor.this.subject = subject;— sets the subject.this.priority = priority;— sets the priority.this.daysOpen = daysOpen;— sets the days open.}— closes the constructor.}— closes the class.- (blank line)
List<TicketSummary> openTickets = new List<TicketSummary>{— a dashboard's worth of tickets.new TicketSummary('Login failure', 'High', 2),— one ticket, all three fields together.new TicketSummary('Slow report load', 'Medium', 5)— another.};— closes the list literal.
A dashboard displaying open support tickets needs several fields per ticket shown together — exactly the case where a List<sObject> (a real Salesforce record) or a custom wrapper class like TicketSummary (useful when the data doesn't map cleanly to one object) both outperform several parallel primitive lists.
Exercise
Write a wrapper class EmployeeSummary with name and yearsOfService fields, then build a List<EmployeeSummary> with two employees.
Show hint
Give EmployeeSummary a constructor accepting both fields.
Custom Types in Collections: Wrapper Classes Quiz
My Notes
Log in to keep private notes on this lesson.
Questions about this lesson
No questions yet — be the first to ask.
Log in to ask a question about this lesson.
Summary
A collection isn't limited to primitives — storing a custom class in a List, Set, or Map (a "wrapper class" pattern) lets each item carry several related pieces of data together.