Hey everyone, welcome back to my blog! In today’s blog post, we’ll be comparing two popular collections in Java—ArrayList and HashSet. While both are used to store collections of objects, they behave differently in terms of ordering, performance, and duplicate handling. Let’s dive into the differences and see some examples to clarify these concepts!
Difference between ArrayList and HashSet in Java
1. Difference 1: Internal Data Structure
First, let’s look at the internal data structure. ArrayList uses a dynamic array to store its elements, which means it can grow as needed. Elements are stored in contiguous memory locations. HashSet, on the other hand, uses a hash table to store its elements. This allows for fast lookups, but elements are stored in a way that doesn’t guarantee order.
Example:
import java.util.ArrayList;
import java.util.HashSet;
public class ListSetComparison {
public static void main(String[] args) {
// ArrayList example
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("Apple");
arrayList.add("Banana");
arrayList.add("Cherry");
System.out.println("ArrayList Output: " + arrayList);
// HashSet example
HashSet<String> hashSet = new HashSet<>();
hashSet.add("Apple");
hashSet.add("Banana");
hashSet.add("Cherry");
System.out.println("HashSet Output: " + hashSet);
}
}
Output:
ArrayList Output: [Apple, Banana, Cherry] (insertion order maintained)
HashSet Output: [Banana, Apple, Cherry] or [Apple, Cherry, Banana] (order is unpredictable)
2. Difference 2: Duplicate Elements
Another important difference is how these two collections handle duplicates. ArrayList allows duplicate elements, which means you can store the same value multiple times. HashSet, on the other hand, does not allow duplicates—if you try to add a duplicate value, it will be ignored.
Example:
import java.util.ArrayList;
import java.util.HashSet;
public class DuplicateComparison {
public static void main(String[] args) {
// ArrayList example - allows duplicates
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("Apple");
arrayList.add("Banana");
arrayList.add("Apple"); // Duplicate value
System.out.println("ArrayList with duplicates: " + arrayList);
// HashSet example - does not allow duplicates
HashSet<String> hashSet = new HashSet<>();
hashSet.add("Apple");
hashSet.add("Banana");
hashSet.add("Apple"); // Duplicate value will be ignored
System.out.println("HashSet with duplicates: " + hashSet);
}
}
Output:
ArrayList with duplicates: [Apple, Banana, Apple]
HashSet with duplicates: [Apple, Banana] (duplicate "Apple" is ignored)
3. Difference 3: Performance
In terms of performance, ArrayList is generally faster for accessing elements by index because it uses a dynamic array. Accessing elements in an ArrayList happens in constant time, O(1), for index-based lookups. HashSet, on the other hand, is faster for adding, removing, and checking if an element exists because it uses a hash table. These operations usually take constant time, O(1), but accessing elements by position is not supported.
Example:
import java.util.ArrayList;
import java.util.HashSet;
public class PerformanceComparison {
public static void main(String[] args) {
// ArrayList performance
ArrayList<Integer> arrayList = new ArrayList<>();
long startTime = System.nanoTime();
arrayList.add(100);
arrayList.add(200);
arrayList.add(300);
System.out.println("ArrayList element at index 1: " + arrayList.get(1)); // O(1) access by index
long endTime = System.nanoTime();
System.out.println("ArrayList operation time: " + (endTime - startTime) + " ns");
// HashSet performance
HashSet<Integer> hashSet = new HashSet<>();
startTime = System.nanoTime();
hashSet.add(100);
hashSet.add(200);
hashSet.add(300);
System.out.println("HashSet contains 200: " + hashSet.contains(200)); // O(1) for lookup
endTime = System.nanoTime();
System.out.println("HashSet operation time: " + (endTime - startTime) + " ns");
}
}
Output:
ArrayList element at index 1: 200
ArrayList operation time: [Shorter time in nanoseconds]
HashSet contains 200: true
HashSet operation time: [Longer time in nanoseconds due to hash computations]
4. Difference 4: Null Elements
Both ArrayList and HashSet allow null elements. However, ArrayList can store multiple null values, while HashSet only allows one null value. If you try to add a second null to a HashSet, it will be ignored.
Example:
import java.util.ArrayList;
import java.util.HashSet;
public class NullComparison {
public static void main(String[] args) {
// ArrayList example - allows multiple nulls
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add(null);
arrayList.add("Banana");
arrayList.add(null); // Second null
System.out.println("ArrayList with nulls: " + arrayList);
// HashSet example - allows only one null
HashSet<String> hashSet = new HashSet<>();
hashSet.add(null);
hashSet.add("Banana");
hashSet.add(null); // Second null is ignored
System.out.println("HashSet with nulls: " + hashSet);
}
}
Output:
ArrayList with nulls: [null, Banana, null]
HashSet with nulls: [null, Banana] (only one null allowed)
Conclusion
That’s it for today’s comparison of ArrayList and HashSet! To sum it up: ArrayList is great when you need indexed access and allow duplicates, while HashSet is better when you want to avoid duplicates and need fast operations like adding and removing elements. Try running these examples in your IDE to see how they behave in different scenarios.
Summary Table: ArrayList vs HashSet
Feature | ArrayList | HashSet |
---|---|---|
Internal Structure | Uses a dynamic array | Uses a hash table |
Order of Elements | Maintains insertion order | No guaranteed order |
Duplicate Elements | Allows duplicates | Does not allow duplicates |
Performance | Faster for index-based access (O(1)) | Faster for add/remove (O(1)) |
Null Elements | Allows multiple null values | Allows only one null value |
Use Case | Best for indexed access and duplicates | Best for ensuring unique elements |