00:00

Difference Between List and Set in Java

List and Set are both sub-interfaces of Collection, but they model different ideas:

  • A List is an ordered sequence that allows duplicates and gives access by index, like a numbered to-do list.
  • A Set is a collection of unique elements with no index, like a set of tags or a guest list where each name appears once.

1. Comparison Table

AspectListSet
DuplicatesAllowedNot allowed (add returns false)
OrderInsertion order (positional)Depends on implementation: none, insertion or sorted
Index accessget(i), set(i, x), add(i, x), indexOfNone
NullAny number of nullsHashSet/LinkedHashSet: one null; TreeSet: none
Main implementationsArrayList, LinkedList, CopyOnWriteArrayListHashSet, LinkedHashSet, TreeSet, EnumSet
contains()O(n) for ArrayListO(1) for HashSet, O(log n) for TreeSet
IteratorIterator and bidirectional ListIteratorIterator only
EqualitySame elements in the same orderSame elements, order ignored
Relies onequals()equals() + hashCode(), or compareTo() for TreeSet

2. Same Data, Different Results

ListVsSet.java
import java.util.*;

public class ListVsSet {
    public static void main(String[] args) {
        String[] tags = {"java", "spring", "java", "kafka", "spring", "docker"};

        List<String> list = new ArrayList<>(Arrays.asList(tags));
        Set<String> hash = new HashSet<>(Arrays.asList(tags));
        Set<String> linked = new LinkedHashSet<>(Arrays.asList(tags));
        Set<String> tree = new TreeSet<>(Arrays.asList(tags));

        System.out.println("List          : " + list + "  (duplicates kept, insertion order)");
        System.out.println("HashSet       : " + hash + "  (no duplicates, no guaranteed order)");
        System.out.println("LinkedHashSet : " + linked + "  (insertion order)");
        System.out.println("TreeSet       : " + tree + "  (sorted)");

        System.out.println("list.get(2)   = " + list.get(2) + "  (index access)");
        System.out.println("list.indexOf(\"kafka\") = " + list.indexOf("kafka"));
        System.out.println("set.add(\"java\") again returns " + hash.add("java"));
    }
}
Output
List          : [java, spring, java, kafka, spring, docker]  (duplicates kept, insertion order)
HashSet       : [spring, java, kafka, docker]  (no duplicates, no guaranteed order)
LinkedHashSet : [java, spring, kafka, docker]  (insertion order)
TreeSet       : [docker, java, kafka, spring]  (sorted)
list.get(2)   = java  (index access)
list.indexOf("kafka") = 3
set.add("java") again returns false

3. Removing Duplicates and Fast Lookups

Dedupe.java
import java.util.*;

public class Dedupe {
    record Email(String address) { }   // records implement equals/hashCode, so sets work

    public static void main(String[] args) {
        List<Integer> orderIds = List.of(105, 101, 105, 103, 101);
        List<Integer> unique = new ArrayList<>(new LinkedHashSet<>(orderIds));   // remove duplicates, keep order
        System.out.println("unique ids: " + unique);

        Set<Email> subscribers = new HashSet<>();
        subscribers.add(new Email("asha@example.com"));
        subscribers.add(new Email("asha@example.com"));
        System.out.println("subscribers: " + subscribers.size());

        // contains(): O(1) average for HashSet vs O(n) for ArrayList
        List<Integer> big = new ArrayList<>();
        for (int i = 0; i < 200_000; i++) big.add(i);
        Set<Integer> bigSet = new HashSet<>(big);
        long t1 = System.nanoTime(); for (int i = 0; i < 2_000; i++) big.contains(199_999);
        long t2 = System.nanoTime(); for (int i = 0; i < 2_000; i++) bigSet.contains(199_999);
        long t3 = System.nanoTime();
        System.out.println("HashSet.contains much faster than List.contains: " + ((t2 - t1) > 10 * (t3 - t2)));
    }
}
Output
unique ids: [105, 101, 103]
subscribers: 1
HashSet.contains much faster than List.contains: true
  • Passing a list through a LinkedHashSet removes duplicates while keeping the original order.
  • Sets rely on equals and hashCode; records generate both, so equal records count once.
  • Membership tests on a HashSet are constant time, while ArrayList.contains scans the whole list.

4. When to Use Which

Use a List when…Use a Set when…
Order or position matters (playlist, steps, history)Each element must be unique (user IDs, tags, permissions)
Duplicates are meaningful (order lines, log entries)You frequently check "is X present?"
You need index access or sorting in placeYou need set operations: union, intersection, difference

5. Summary

  • List: ordered, duplicates allowed, index access.
  • Set: unique elements, no index, ordering depends on the implementation.
  • Sets give fast contains and need correct equals/hashCode.
  • Convert a list to a LinkedHashSet to remove duplicates while preserving order.

Related Tutorials