Header Ad Section

Key Differences between Set vs List in Java Programming



 





Introduction

Selecting the appropriate data structure for your Java application requires a thorough understanding of the distinctions between Set and List. Although they serve different functions, both of them are crucial parts of the Java Collections Framework. The main differences between Set and List in Java will be discussed in this article.

Key Differences between Set and List in Java

  1. Order of the Elements in the Collection
  2. Handling Duplicate Elements
  3. Access by Index
  4. Performance Comparison based on the performed operations
  5. Support for Null Elements Handling
  6. Difference Between its implementation



Let's discuss more deeply about the main differences of Set and List in Java Collection Framework.

1. Order of the Elements in the Collection

  • Set: Does not guarantee the order of elements (except for specific implementations like LinkedHashSet which maintains insertion order, or TreeSet which maintains elements in sorted order).
  • List: Maintains the insertion order of elements. The order in which you add elements is the order in which they are retrieved.


 import java.util.Arrays;
 import java.util.HashSet;
import java.util.List;
import java.util.Set;

    
class Main {
public static void main(String[] args) {

List<String> list = Arrays.asList("cat", "bag", "apple");
System.out.println(list);

Set<String> set = new HashSet<>();
set.add("cat");
set.add("bag");
set.add("apple");
System.out.println(set);
}
}


 Output:
[cat, bag, apple] [apple, cat, bag] Process finished with exit code 0


2. Handling Duplicate Elements

  • Set: Does not allow duplicate elements. Every element in a Set must be unique.
  • List: Allows duplicate elements. You can have multiple occurrences of the same element in a List.


 import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;


class Main{
public static void main(String[] args) {

List<String> list = Arrays.asList("john", "peter", "john");
System.out.println(list);

Set<String> set = new HashSet<>();
set.add("john");
set.add("peter");
set.add("john");
System.out.println(set);
}
}


Output:
[john, peter, john] [peter, john] Process finished with exit code 0


3. Access by Index

  • Set: Does not provide access by index. There are no methods to get an element by its position.
  • List: Provides access by index. You can retrieve, modify, or remove elements using their position (Eg: list.get(index)).


 import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;


class Main{
public static void main(String[] args) {

List<String> list = Arrays.asList("cat", "bag", "apple");
System.out.println(list.get(0)); // Gives output as "cat"

Set<String> set = new HashSet<>();
set.add("cat");
set.add("bag");
set.add("apple");
System.out.println(set.get(0)); // Compile Error: cannot find symbol
}
}


Output:
cat java: cannot find symbol symbol: method get(int) location: variable set of type java.util.Set<java.lang.String>


4. Performance Comparison based on the Performed Operations

  • Set: Generally offers better performance for operations like searching and adding when compared to a List, especially with implementations like HashSet (O(1) for basic operations).
  • List: May have slower search times (O(n)) for unsorted lists, but indexing operations are O(1) for implementations like ArrayList.

    
     import java.util.*;


    class Main{
    public static void main(String[] args) {


    // Set (HashSet)
    Set<Integer> hashSet = new HashSet<>();
    for (int i = 1; i <= 1000000; i++) {
    hashSet.add(i);
    }
    long startTime = System.nanoTime();
    boolean setContains = hashSet.contains(500000); // O(1) search
    long endTime = System.nanoTime();
    System.out.println("HashSet search time: " + (endTime - startTime) + " ns");

    // List (ArrayList)
    List<Integer> arrayList = new ArrayList<>();
    for (int i = 1; i <= 1000000; i++) {
    arrayList.add(i);
    }
    startTime = System.nanoTime();
    boolean listContains = arrayList.contains(500000); // O(n) search
    endTime = System.nanoTime();
    System.out.println("ArrayList search time: " + (endTime - startTime) + " ns");
    }
    }

    Output:
    HashSet search time: 67400 ns ArrayList search time: 20147900 ns Process finished with exit code 0

    5. Support for Null Elements Handling

  • Set:
                1. HashSet: Allows only a single null element.             
  • 
     import java.util.HashSet;
    import java.util.Set;


    class Main{
    public static void main(String[] args) {


    Set<String> hashSet = new HashSet<>();
    hashSet.add(null);
    hashSet.add(null); // Duplicate null
    System.out.println(hashSet); // Ignore duplicates
    }
    }

    Output:
    [null] Process finished with exit code 0
     

    2. LinkedHashSet: also allows only a single null element.

    
     import java.util.LinkedHashSet;
    import java.util.Set;


    class Main{
    public static void main(String[] args) {


    Set<String> linkedHashSet = new LinkedHashSet<>();
    linkedHashSet.add(null);
    linkedHashSet.add(null); // Duplicate null
    System.out.println(linkedHashSet); // Ignore duplicates
    }
    }

    Output:
    [null] Process finished with exit code 0  


    3. TreeSet: Doesn't allow null because it relies on sorting/comparison.

    
     import java.util.TreeSet;
    import java.util.Set;


    class Main{
    public static void main(String[] args) {

    // TreeSet doesn't allow null
    try {
    Set<String> treeSet = new TreeSet<>();
    treeSet.add(null);
    } catch (NullPointerException e) {
    System.out.println("TreeSet doesn't allow null: " + e.getMessage());
    }
    }
    }

    Output:
    TreeSet doesn't allow null: null Process finished with exit code 0  

     

  • List: Allows multiple null elements in implementations like ArrayList and LinkedList.

    
     import java.util.ArrayList;
    import java.util.List;


    class Main{
    public static void main(String[] args) {

    // ArrayList allows multiple null elements
    List<String> arrayList = new ArrayList<>();
    arrayList.add(null);
    arrayList.add(null);
    System.out.println("ArrayList: " + arrayList); // Allows multiple null elements
    }
    }
    
     Output:
    ArrayList: [null, null] Process finished with exit code 0


    6. Java Set Implementation vs List Implementation

  • Set:
    • HashSet: Unordered, does not maintain insertion order.
    • LinkedHashSet: Maintains insertion order.
    • TreeSet: Maintains elements in sorted order (requires Comparable or a Comparator).
  • List:
    • ArrayList: Resizable array, faster for random access.
    • LinkedList: Doubly-linked list, faster for insertions and deletions.

    
     import java.util.*;


    class Main{
    public static void main(String[] args) {

    // HashSet: Unordered
    Set<Integer> hashSet = new HashSet<>();
    hashSet.add(42);
    hashSet.add(3);
    hashSet.add(15);
    hashSet.add(8);
    hashSet.add(23);
    System.out.println("HashSet (Unordered): " + hashSet);

    // LinkedHashSet: Maintains insertion order
    Set<Integer> linkedHashSet = new LinkedHashSet<>();
    linkedHashSet.add(42);
    linkedHashSet.add(3);
    linkedHashSet.add(15);
    linkedHashSet.add(8);
    linkedHashSet.add(23);
    System.out.println("LinkedHashSet (Insertion Order): " + linkedHashSet);

    // TreeSet: Sorted order
    Set<Integer> treeSet = new TreeSet<>();
    treeSet.add(42);
    treeSet.add(3);
    treeSet.add(15);
    treeSet.add(8);
    treeSet.add(23);
    System.out.println("TreeSet (Sorted Order): " + treeSet);

    // ArrayList: Resizable array, random access
    List<Integer> arrayList = new ArrayList<>();
    arrayList.add(42);
    arrayList.add(3);
    arrayList.add(15);
    arrayList.add(8);
    arrayList.add(23);
    System.out.println("ArrayList: " + arrayList);
    System.out.println("Random Access (Index 2): " + arrayList.get(2));

    // LinkedList: Doubly-linked list
    List<Integer> linkedList = new LinkedList<>();
    linkedList.add(42);
    linkedList.add(3);
    linkedList.add(15);
    linkedList.add(8);
    linkedList.add(23);
    System.out.println("LinkedList: " + linkedList);
    ((LinkedList<Integer>) linkedList).addFirst(0);
    System.out.println("After adding at the beginning: " + linkedList);
    }
    }

    Output:
    HashSet (Unordered): [3, 23, 8, 42, 15] LinkedHashSet (Insertion Order): [42, 3, 15, 8, 23] TreeSet (Sorted Order): [3, 8, 15, 23, 42] ArrayList: [42, 3, 15, 8, 23] Random Access (Index 2): 15 LinkedList: [42, 3, 15, 8, 23] After adding at the beginning: [0, 42, 3, 15, 8, 23] Process finished with exit code 0


    Post a Comment

    0 Comments