beginner
Fundamentals

Apex Practice Problems for Beginners (With Solutions)

Seven Apex practice problems with worked solutions. Loops, conditionals, string methods, and collections, each one linked to a challenge you can run in a real org.

7 min read
Warren Walters
apex
beginner
practice
fundamentals

TL;DR

Seven small Apex problems, each with a worked solution: sum a list, find the largest number, FizzBuzz, reverse a string, count vowels, remove duplicates, and turn a score into a letter grade. They cover loops, conditionals, string methods, and collections. Every one links to a challenge where you write the code yourself.

How to Run These

None of this needs a trigger, a test class, or a deploy. Open the Developer Console in any org, choose Debug → Open Execute Anonymous Window, paste a block, and tick Open Log. The System.debug line at the end of each solution is what you read in the log.

Every block below stands on its own. Nothing carries over from the block above it, so you can copy any single one and run it.

New to the language? Start with Say Hello, then come back. The rest of this post assumes you know what a variable is.

Problem 1: Add Up a List of Numbers

The question: given a list of integers, return the total.

List<Integer> scores = new List<Integer>{ 10, 25, 8, 42 };
Integer total = 0;
for (Integer score : scores) {
    total += score;
}
System.debug(total);

The for (Integer score : scores) form is the enhanced for loop. It hands you each item in turn. You do not manage an index, so you cannot walk off the end of the list.

One thing to watch: total starts at 0, not null. Adding a number to null in Apex throws a null pointer exception. Any running total you build needs a starting value.

Write it yourself on Sum a List of Integers.

Problem 2: Find the Largest Number

The question: given a list of integers, return the biggest one.

List<Integer> scores = new List<Integer>{ 10, 25, 8, 42 };
Integer largest = null;
for (Integer score : scores) {
    if (largest == null || score > largest) {
        largest = score;
    }
}
System.debug(largest);

Most people start largest at 0 instead of null. That works until the list is all negative numbers, and then it returns 0, which is not in the list at all. Starting at null and checking for it first handles every case, including an empty list.

The || short circuits. When largest is still null, Apex never evaluates score > largest, so the comparison never sees a null.

Try it on Find Maximum Number.

Problem 3: FizzBuzz

The question: print the numbers 1 to 15. Replace multiples of three with Fizz, multiples of five with Buzz, and multiples of both with FizzBuzz.

List<String> output = new List<String>();
for (Integer i = 1; i <= 15; i++) {
    if (Math.mod(i, 15) == 0) {
        output.add('FizzBuzz');
    } else if (Math.mod(i, 3) == 0) {
        output.add('Fizz');
    } else if (Math.mod(i, 5) == 0) {
        output.add('Buzz');
    } else {
        output.add(String.valueOf(i));
    }
}
System.debug(String.join(output, ', '));

Two things here catch Apex newcomers.

First, Apex has no % operator. If you have written FizzBuzz in Java or JavaScript, your fingers will type i % 3 and the code will not compile. Use Math.mod(i, 3) instead.

Second, the order of the branches is the whole problem. Check the both case first. If you test for Fizz before FizzBuzz, then 15 matches the three branch, prints Fizz, and the FizzBuzz branch never runs.

Solve it on Fizz Buzz.

Problem 4: Reverse a String

The question: given a word, return it backwards.

String word = 'Salesforce';
String reversed = '';
for (Integer i = word.length() - 1; i >= 0; i--) {
    reversed += word.substring(i, i + 1);
}
System.debug(reversed);

This walks the string from the last index down to zero. substring(i, i + 1) pulls one character, because Apex substring takes a start index and an end index, and the end index is exclusive.

Note that word.length() - 1 is the last valid index, not word.length(). Indexes start at zero, so a ten character word runs from 0 to 9. Asking for index 10 throws a string index out of bounds error.

Build it on Reverse String.

Problem 5: Count the Vowels

The question: given a phrase, count how many vowels it contains.

String phrase = 'Lightning Challenge';
String vowels = 'aeiou';
Integer count = 0;
for (Integer i = 0; i < phrase.length(); i++) {
    String letter = phrase.substring(i, i + 1).toLowerCase();
    if (vowels.contains(letter)) {
        count++;
    }
}
System.debug(count);

The toLowerCase() call is doing real work. Without it, the capital L and C in the phrase would never match a vowel list written in lowercase, and a word like Apple would come back with one vowel instead of two. Case is the bug that hides in almost every string problem.

Using contains on a five character string is fine here. For a bigger set of characters you would reach for a Set<String>, which looks up in constant time instead of scanning.

Count them on Count Vowels.

Problem 6: Strip Out Duplicates

The question: given a list with repeats, return a list with each value once.

List<String> names = new List<String>{ 'Ada', 'Grace', 'Ada', 'Alan' };
Set<String> seen = new Set<String>();
List<String> unique = new List<String>();
for (String name : names) {
    if (seen.add(name)) {
        unique.add(name);
    }
}
System.debug(unique);

Set.add() returns a Boolean. It is true when the value was new and false when the set already had it. That one return value gives you the whole filter, and it keeps the original order.

If order does not matter, the short version is two lines:

List<String> names = new List<String>{ 'Ada', 'Grace', 'Ada', 'Alan' };
Set<String> unique = new Set<String>(names);
System.debug(new List<String>(unique));

A set constructor takes a list and drops the repeats for you. Sets have no defined order, though, so do not use this version when the sequence matters.

Deduplicate on Remove Duplicates.

Problem 7: Turn a Score Into a Letter Grade

The question: given a score from 0 to 100, return A, B, C, D, or F.

Integer score = 83;
String grade;
if (score >= 90) {
    grade = 'A';
} else if (score >= 80) {
    grade = 'B';
} else if (score >= 70) {
    grade = 'C';
} else if (score >= 60) {
    grade = 'D';
} else {
    grade = 'F';
}
System.debug(grade);

The chain reads top down and stops at the first match. That is why it starts at 90 and works downward. Flip it so score >= 60 comes first and every passing score returns a D.

You also do not need an upper bound on each branch. By the time Apex reaches score >= 80, it already knows the score is under 90, because the branch above did not match.

Work it on Letter Grade From Score.

What These Seven Have in Common

None of them are about Salesforce. They are about the language.

That is deliberate. Most Apex bugs a new developer writes are not platform bugs. They are a loop that starts at the wrong index, a null that was never initialized, or an if chain in the wrong order. Those habits do not change when you move from a list of integers to a list of Accounts.

Once these feel routine, the next step is the platform layer: querying records with SOQL, writing them back with DML, and staying inside the governor limits. Our SOQL practice problems post picks up exactly there, and Insert an Account is a good first DML challenge.

Where To Practice Next

Reading a solution is not the same as writing one. Each problem above has a challenge that grades your code against a real org:

Write the code before you read the answer. That is the part that sticks.

WW

About Warren Walters

Salesforce MVP and transformative mentor with 8+ years in the Salesforce realm. Founder of Lightning Challenge, dedicated to nurturing the next generation of Salesforce talent through hands-on practice and real-world coding challenges.

Visit Profile →
Share:

Related Posts