Verified for the 2025 AP Computer Science A exam•Citation:
Imagine your music playlist, book collection, or a list of high scores - wouldn't it be nice if they were organized? That's what sorting is all about! In Java, we often need to arrange the elements in arrays and ArrayLists in a specific order (like alphabetically or numerically). This guide covers how sorting algorithms work and how to implement them in Java using iteration (loops) and selection (if-statements).
Sorting is the process of arranging elements in a specific order. Think of it like organizing books on a shelf - you might arrange them:
Before we dive into sorting, let's clarify what we're sorting:
Array: A fixed-size collection of elements of the same type (like int[]
or String[]
). Arrays have a predetermined size that can't change after creation.
ArrayList: A dynamic-sized collection from Java's built-in library that can grow and shrink as needed. An ArrayList stores objects (not primitives directly) and provides helpful methods for managing data. You need to import it with: import java.util.ArrayList;
In Java, we commonly sort both arrays and ArrayLists to:
In this unit, we focus on two main sorting algorithms:
Algorithm | How It Works | Good For |
---|---|---|
Selection Sort | Repeatedly finds the smallest (or largest) element and moves it to its final position | Simple to implement, works well for small datasets |
Insertion Sort | Builds the final sorted array one item at a time | Works well for nearly sorted data, efficient for small datasets |
Selection sort works like this:
public static void selectionSort(int[] arr) { for (int i = 0; i < arr.length - 1; i++) { // Find the minimum element in the unsorted portion int minIndex = i; for (int j = i + 1; j < arr.length; j++) { if (arr[j] < arr[minIndex]) { minIndex = j; } } // Swap the found minimum element with the first element int temp = arr[minIndex]; arr[minIndex] = arr[i]; arr[i] = temp; } }
public static void selectionSort(ArrayList<Integer> list) { for (int i = 0; i < list.size() - 1; i++) { // Find the minimum element in the unsorted portion int minIndex = i; for (int j = i + 1; j < list.size(); j++) { if (list.get(j) < list.get(minIndex)) { minIndex = j; } } // Swap the found minimum element with the first element int temp = list.get(minIndex); list.set(minIndex, list.get(i)); list.set(i, temp); } }
Consider sorting [5, 3, 8, 1, 2]:
Insertion sort works like this:
Think of it like sorting cards in your hand as you pick them up!
public static void insertionSort(int[] arr) { for (int i = 1; i < arr.length; i++) { int currentElement = arr[i]; int j = i - 1; // Move elements that are greater than currentElement // to one position ahead of their current position while (j >= 0 && arr[j] > currentElement) { arr[j + 1] = arr[j]; j--; } arr[j + 1] = currentElement; } }
public static void insertionSort(ArrayList<Integer> list) { for (int i = 1; i < list.size(); i++) { int currentElement = list.get(i); int j = i - 1; // Move elements that are greater than currentElement // to one position ahead of their current position while (j >= 0 && list.get(j) > currentElement) { list.set(j + 1, list.get(j)); j--; } list.set(j + 1, currentElement); } }
Consider sorting [5, 3, 8, 1, 2]:
Java provides built-in methods to sort arrays and ArrayLists:
import java.util.Arrays; // Sorting an array of primitives int[] numbers = {5, 3, 8, 1, 2}; Arrays.sort(numbers); // Now numbers = [1, 2, 3, 5, 8] // Sorting an array of objects String[] names = {"Charlie", "Alice", "Bob"}; Arrays.sort(names); // Now names = ["Alice", "Bob", "Charlie"]
import java.util.Collections; import java.util.ArrayList; ArrayList<Integer> numbers = new ArrayList<>(); numbers.add(5); numbers.add(3); numbers.add(8); numbers.add(1); numbers.add(2); Collections.sort(numbers); // Now numbers = [1, 2, 3, 5, 8]
When sorting custom objects, Java needs to know how to compare them. There are two ways to do this:
public class Student implements Comparable<Student> { private String name; private double gpa; // Constructor and other methods... @Override public int compareTo(Student other) { // Sort by GPA (highest first) return Double.compare(other.gpa, this.gpa); } } // Now you can sort students ArrayList<Student> students = new ArrayList<>(); // ... add students to the list Collections.sort(students); // Sorts by GPA (highest first)
import java.util.Comparator; // Sort by name class NameComparator implements Comparator<Student> { @Override public int compare(Student s1, Student s2) { return s1.getName().compareTo(s2.getName()); } } // Now you can sort using this comparator Collections.sort(students, new NameComparator()); // Sorts alphabetically by name
How do we know which sorting algorithm is better? We measure:
We use statement execution counts to measure how many steps a sorting algorithm takes. This is an informal way to understand efficiency.
Algorithm | Best Case | Average Case | Worst Case |
---|---|---|---|
Selection Sort | O(n²) | O(n²) | O(n²) |
Insertion Sort | O(n) | O(n²) | O(n²) |
What does O(n²) mean? If you have n items to sort, the algorithm takes approximately n² steps. So if sorting 100 items takes 10,000 steps, sorting 200 items would take about 40,000 steps (4× slower, not just 2×).
This measures how much extra memory the algorithm uses:
Both selection and insertion sort use O(1) space - only a few extra variables regardless of list size
Some other algorithms (not covered here) use more space
compareTo()
or compare()
methods are correctly implementedSorting is a fundamental operation that helps us organize data in a useful way. While selection sort and insertion sort might not be the fastest algorithms out there, understanding how they work builds a foundation for learning more complex sorting techniques. Remember, Java's built-in sorting methods are usually the best choice for real applications, but knowing how sorting works "under the hood" is valuable for any programmer. Now you're ready to keep your data nice and organized!