ArrayList Sorting in Java
Problem
Collections.sort() rearranges a list in place according to its elements' natural ordering — ascending for numbers, alphabetical for strings — with no comparator needed.
Given an ArrayList of integers in no particular order, sort it into ascending order.
Java Program
import java.util.ArrayList;
import java.util.Collections;
public class ArrayListSorting {
public static void main(String[] args) {
ArrayList<Integer> numbers = new ArrayList<>();
numbers.add(42);
numbers.add(17);
numbers.add(8);
numbers.add(23);
Collections.sort(numbers); // rearranges numbers in place, ascending
System.out.println("Sorted: " + numbers);
}
}Output
Core Logic
Collections.sort() rearranges the list's existing elements directly, using each Integer's natural ascending order, without building a separate sorted copy.
- 1The list starts as
[42, 17, 8, 23], built by fouradd()calls in that order. - 2
Collections.sort(numbers)reorders the list's elements in place, comparing them by their natural ordering — ascending forInteger. - 3No comparator is passed in, so the sort relies on
Integer's owncompareTo(), which orders smaller numbers first. - 4After the call returns,
numbersitself has been rearranged — the sort doesn't produce a new list.
[42, 17, 8, 23] rearranges it into [8, 17, 23, 42], smallest to largest.Key Point: Collections.sort() modifies the list it's given — the original unsorted order is gone once the call returns, unlike the stream-based approach, which builds a new sorted list and leaves the original untouched.
Why: Collections.sort() uses a Timsort-derived merge sort, which runs in O(n log n) comparisons and needs a temporary working array proportional to the list's size.
Key Concepts
Approach 2: Java 8
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class ArrayListSortingStream {
public static void main(String[] args) {
ArrayList<Integer> numbers = new ArrayList<>();
numbers.add(42);
numbers.add(17);
numbers.add(8);
numbers.add(23);
// Produces a new sorted list — the original numbers list is untouched
List<Integer> sorted = numbers.stream().sorted().collect(Collectors.toList());
System.out.println("Sorted: " + sorted);
}
}
Output
Core Logic
A stream can sort declaratively, producing a brand-new sorted list instead of rearranging the original in place.
- 1
numbers.stream()opens a stream over the original, unsorted list. - 2
.sorted()orders the stream's elements using their natural ordering, the same rule Collections.sort() uses. - 3
.collect(Collectors.toList())gathers the sorted elements into a brand-newList<Integer>. - 4The original
numberslist is never touched —sortedis a separate object.
[42, 17, 8, 23] through .sorted() produces the same [8, 17, 23, 42] result, but as a new list.Key Point: Because streams don't mutate their source, the original list stays in its original order after this call — useful when the unsorted order still needs to be available elsewhere in the program.
Why: sorted() performs the same O(n log n) comparison-based sort internally, and collect() materializes a full new list of size n rather than reusing the original's storage.