Useful JavaExtra· 40 min read

The Collections Framework & Sorting

Beyond ArrayList and HashMap lies a whole family of collections — Sets, Queues and sorted maps — plus tools to sort them your way.

What you will learn

  • Pick a Set, Queue or sorted collection for the job
  • Sort a list with Collections.sort and a Comparator
  • Make your own objects sortable with Comparable

A family of containers

You already met ArrayList (an ordered list) and HashMap (key to value). Java groups all its containers into the Collections Framework — a family of ready-made data structures, each good at one job. Picking the right one makes your code simpler and faster.

CollectionHoldsSpecial power
ArrayListAn ordered listFast access by position, keeps duplicates
HashSetA set of unique itemsAutomatically refuses duplicates
TreeSetA set, kept sortedAlways in sorted order
LinkedList / QueueA waiting lineAdd at one end, remove from the other (first in, first out)
TreeMapKey to value, sorted by keyKeys come out in order

A Set removes duplicates for you

A Set is a collection that cannot contain duplicates. Add the same value twice and the second add is simply ignored. This is perfect for collecting unique things, like the distinct words in a sentence.

A HashSet keeps only unique values
import java.util.HashSet;

public class Main {
    public static void main(String[] args) {
        HashSet<String> tags = new HashSet<>();
        tags.add("java");
        tags.add("code");
        tags.add("java");   // duplicate — ignored

        System.out.println("Unique tags: " + tags.size());
        System.out.println("Has code? " + tags.contains("code"));
    }
}

Note: Output: Unique tags: 2 Has code? true We added "java" twice but the size is 2, because a Set keeps only unique items. contains checks membership instantly. Note a HashSet does not promise any particular order — use a TreeSet instead if you want the items sorted.

A Queue is a waiting line

A Queue works like a queue at a shop: the first one in is the first one out (FIFO). You offer items to the back and poll them from the front.

A Queue serves people in the order they arrived
import java.util.LinkedList;
import java.util.Queue;

public class Main {
    public static void main(String[] args) {
        Queue<String> line = new LinkedList<>();
        line.offer("Asha");
        line.offer("Ravi");
        line.offer("Mia");

        System.out.println("Serving: " + line.poll());   // first in, first out
        System.out.println("Next up: " + line.peek());    // look without removing
        System.out.println("Still waiting: " + line.size());
    }
}

Note: Output: Serving: Asha Next up: Ravi Still waiting: 2 offer added three people to the back of the line. poll removed and returned Asha (the first to arrive). peek shows the next person (Ravi) without removing them. That first-in-first-out behaviour is exactly what a queue is for.

Sorting a list

A very common task is putting a list in order. For lists of built-in types (numbers, Strings), Collections.sort does it in one call.

Collections.sort orders a list for you
import java.util.ArrayList;
import java.util.Collections;

public class Main {
    public static void main(String[] args) {
        ArrayList<Integer> scores = new ArrayList<>();
        scores.add(72);
        scores.add(40);
        scores.add(95);

        Collections.sort(scores);            // smallest to largest
        System.out.println(scores);

        Collections.sort(scores, Collections.reverseOrder());   // largest first
        System.out.println(scores);
    }
}

Note: Output: [40, 72, 95] [95, 72, 40] The first sort put the numbers from smallest to largest. Passing Collections.reverseOrder() flipped it to largest first. For numbers and Strings, Java already knows the natural order, so this just works.

Sorting your own objects (Comparable)

What about sorting a list of your own objects, like Students? Java does not know whether to sort by name or by score, so you must tell it. One way is to make the class implement Comparable and write a compareTo method that defines the natural order.

The compareTo rule is simple: return a negative number if this object should come before the other, positive if it should come after, and zero if they are equal. Subtracting two numbers gives exactly that pattern.

Comparable defines the natural order of an object
import java.util.ArrayList;
import java.util.Collections;

public class Student implements Comparable<Student> {
    String name;
    int score;

    Student(String name, int score) {
        this.name = name;
        this.score = score;
    }

    @Override
    public int compareTo(Student other) {
        return this.score - other.score;   // sort by score, low to high
    }

    public static void main(String[] args) {
        ArrayList<Student> students = new ArrayList<>();
        students.add(new Student("Asha", 72));
        students.add(new Student("Ravi", 40));
        students.add(new Student("Mia", 95));

        Collections.sort(students);   // uses compareTo

        for (Student s : students) {
            System.out.println(s.name + ": " + s.score);
        }
    }
}

Note: Output: Ravi: 40 Asha: 72 Mia: 95 Collections.sort called our compareTo on each pair. Because we returned this.score - other.score, lower scores sorted first, so Ravi (40) leads and Mia (95) trails. We taught Java how to compare Students by writing one small method.

A different order on the fly (Comparator)

A class can only have one natural order via Comparable. To sort the same list a different way (say by name instead of score), pass a Comparator — a small throwaway rule for one sort. Modern Java makes this a one-liner:

A Comparator sorts the same list a different way
import java.util.Comparator;

// Sort the same students by name instead, A to Z:
students.sort(Comparator.comparing(s -> s.name));

for (Student s : students) {
    System.out.println(s.name);
}

Note: Output: Asha Mia Ravi Comparator.comparing(s -> s.name) built a rule that compares by the name field, so the list came out alphabetically. Comparable is the one built-in order; a Comparator is a custom order you can supply any time you sort.

Tip: Quick way to choose: need to forbid duplicates? Use a Set. Need a first-in-first-out line? Use a Queue. Need the data kept sorted automatically? Use a TreeSet or TreeMap. Otherwise an ArrayList or HashMap is usually the right default.

Q. You add the same value to a HashSet twice. What happens?

Answer: A Set never holds duplicates. Adding an item that is already present simply has no effect, which is why a Set is the natural choice for collecting unique values.

✍️ Practice

  1. Put five names (with one repeat) into a HashSet and print the size to prove the duplicate was dropped.
  2. Make a Book class implement Comparable to sort by page count, then sort and print an ArrayList of books.

🏠 Homework

  1. Build an ArrayList of Product objects (name and price). Sort it by price low-to-high with Comparable, then sort it by name with a Comparator, printing the list both times.
Want to learn this with a mentor?

CodingClave runs guided, project-based training (28-day, 45-day & 6-month batches).

Explore Training →