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
- Order of the Elements in the Collection
- Handling Duplicate Elements
- Access by Index
- Performance Comparison based on the performed operations
- Support for Null Elements Handling
- 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.
2. Handling Duplicate Elements
- Set: Does not allow duplicate elements. Every element in a
Setmust be unique. - List: Allows duplicate elements. You can have multiple occurrences of the same element in a List.
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.*;
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
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
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
HashSet: Unordered, does not maintain insertion order.LinkedHashSet: Maintains insertion order.TreeSet: Maintains elements in sorted order (requiresComparableor aComparator).
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
0 Comments