CopyOnWriteArraySet is a thread-safe implementation of the Set interface, backed by a CopyOnWriteArrayList. Like CopyOnWriteArrayList, all mutative operations (add, remove, etc.) are implemented by making a fresh copy of the underlying array. It is part of the java.util.concurrent package.
Key Points:
Thread-Safety: All mutative operations are implemented by copying the underlying array, ensuring that the structure is safe from concurrent modifications.
Uniqueness: Since it implements the Set interface, it does not allow duplicate elements.
Iteration Behavior: Iterators for this set never throw ConcurrentModificationException.
Performance: While the data can be iterated safely across multiple threads, the copy-on-write nature can be expensive for frequent modifications. It’s most suitable for cases where iterations vastly outnumber modifications.
Null Values: CopyOnWriteArraySet does not support null values.
Common Methods of CopyOnWriteArraySet
import java.util.Set;
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArraySet;
public class CopyOnWriteArraySetDemo {
public static void main(String[] args) {
// 1. Initialization
Set<String> cowSet = new CopyOnWriteArraySet<>();
System.out.println("Initialized set: " + cowSet);
// 2. Adding elements
cowSet.add("Apple");
cowSet.add("Banana");
cowSet.add("Cherry");
System.out.println("After adding elements: " + cowSet);
// 3. Check for a specific element
System.out.println("Contains 'Apple'? " + cowSet.contains("Apple"));
// 4. Remove an element
cowSet.remove("Banana");
System.out.println("After removing 'Banana': " + cowSet);
// 5. Iterate over the set
Iterator<String> iterator = cowSet.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
// 6. Add element during iteration
for (String item : cowSet) {
if ("Apple".equals(item)) {
cowSet.add("Dragonfruit");
}
System.out.println(item);
}
System.out.println("After adding 'Dragonfruit' during iteration: " + cowSet);
}
}
Output:
Initialized set: [] After adding elements: [Apple, Banana, Cherry] Contains 'Apple'? true After removing 'Banana': [Apple, Cherry] Apple Cherry Apple Cherry After adding 'Dragonfruit' during iteration: [Dragonfruit, Apple, Cherry]
Explanation:
1. An empty CopyOnWriteArraySet of type String is initialized.
2. Elements are added to the set using the add method.
3. The contains method checks if a particular element exists in the set.
4. The remove method is used to delete the string "Banana" from the set.
5. The Iterator is used to traverse and print each element of the set.
6. The special feature of CopyOnWriteArraySet is demonstrated: it allows modifications like add during iteration without ConcurrentModificationException.
7. As we iterate through the set, we add "Dragonfruit" when we encounter "Apple".
Real-World Use Case: Online Classroom Students Registration using CopyOnWriteArraySet
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
class Student {
private String name;
private int studentId;
public Student(String name, int studentId) {
this.name = name;
this.studentId = studentId;
}
@Override
public String toString() {
return "ID: " + studentId + ", Name: " + name;
}
}
public class OnlineClassroom {
public static void main(String[] args) {
// 1. Initialization
Set<Student> registeredStudents = new CopyOnWriteArraySet<>();
System.out.println("Initial registered students: " + registeredStudents);
// 2. Registering students
registeredStudents.add(new Student("Amit Sharma", 101));
registeredStudents.add(new Student("Priya Malhotra", 102));
registeredStudents.add(new Student("Rahul Joshi", 103));
System.out.println("After registration: " + registeredStudents);
// 3. Iterating and registering a student during iteration
for (Student student : registeredStudents) {
System.out.println(student);
if (student.toString().contains("Priya Malhotra")) {
registeredStudents.add(new Student("Deepika Gupta", 104));
}
}
System.out.println("After registering a student during iteration: " + registeredStudents);
}
}
Output:
Initial registered students: [] After registration: [ID: 101, Name: Amit Sharma, ID: 102, Name: Priya Malhotra, ID: 103, Name: Rahul Joshi] ID: 101, Name: Amit Sharma ID: 102, Name: Priya Malhotra ID: 103, Name: Rahul Joshi After registering a student during iteration: [ID: 104, Name: Deepika Gupta, ID: 101, Name: Amit Sharma, ID: 102, Name: Priya Malhotra, ID: 103, Name: Rahul Joshi]
Explanation:
1. An empty CopyOnWriteArraySet of type Student is initialized to keep track of registered students.
2. Students are added to the set using the add method. This ensures that duplicate students (in terms of memory address) won't get registered again.
3. As we iterate through the registered students, we add a new student named "Deepika Gupta" when we encounter "Priya Malhotra".
4. The special feature of CopyOnWriteArraySet is shown here: it allows adding elements during iteration without ConcurrentModificationException.