ภาพรวมของ CopyOnWriteArraySet
CopyOnWriteArraySet เป็น Set ที่ thread-safe ตัวแปรของ ArrayList ทุกครั้งที่เปลี่ยนแปลงจะสร้าง Array ใหม่ เหมาะสำหรับการอ่านมาก เขียนน้อย
ตัวอย่างการใช้งาน size()
ตัวอย่างนี้สาธิตเมธอด size() ซึ่งคืนจำนวนสมาชิกใน Set เป็น O(1)
ขั้นตอนที่ 1-2: สร้างโปรเจกต์และ Layout
สร้างโปรเจกต์ใหม่ ใช้ Layout TextView
ขั้นตอนที่ 3: โค้ด Java
package com.example.myapplication;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
import java.util.concurrent.CopyOnWriteArraySet;
public class MainActivity extends AppCompatActivity {
CopyOnWriteArraySet<String> copyOnWriteArraySet;
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
copyOnWriteArraySet = new CopyOnWriteArraySet<>();
final TextView actionEvent = findViewById(R.id.actionEvent);
copyOnWriteArraySet.add("sai");
copyOnWriteArraySet.add("ram");
copyOnWriteArraySet.add("krishna");
copyOnWriteArraySet.add("prasad");
copyOnWriteArraySet.add("ram"); // Set ไม่รับซ้ำ เก็บแค่ 1 "ram"
actionEvent.setText("" + copyOnWriteArraySet);
actionEvent.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
actionEvent.setText("Size: " + copyOnWriteArraySet.size());
}
});
}
}
พฤติกรรมของ CopyOnWriteArraySet
- เป็น Set - ไม่อนุญาตค่าซ้ำ (Unique elements)
- เพิ่ม "ram" 2 ครั้ง → เก็บได้แค่ 1 ตัว
- size() นับเฉพาะ Unique elements
- ลำดับ: Insertion order (ตามลำดับที่เพิ่มเข้าไปครั้งแรก)
- Thread-safe - Copy-on-write ทุกครั้งที่เขียน
ตัวอย่างข้อมูล
เพิ่ม: "sai", "ram", "krishna", "prasad", "ram" (ซ้ำ) Set จริง: [sai, ram, krishna, prasad] // 4 elements size() = 4
size() ใน CopyOnWriteArraySet vs CopyOnWriteArrayList
| คุณสมบัติ | CopyOnWriteArraySet | CopyOnWriteArrayList |
|---|---|---|
| size() Complexity | O(1) | O(1) |
| Duplicate | ❌ ไม่ได้ | ✅ ได้ |
| get(index) | ❌ ไม่มี | ✅ มี |
| contains() | O(n) - Linear search | O(n) - Linear search |
| Add/Remove | O(n) - Copy array | O(n) - Copy array |
⚠️ ประสิทธิภาพ Copy-on-Write
⚠️ Trade-off:
- Read (size, get, iteration): เร็วมาก O(1) ไม่ต้อง Lock
- Write (add, remove, size change): ช้า O(n) - ต้อง Copy Array ใหม่ทั้งหมด
- เหมาะ: Read-heavy, Write-rare, ข้อมูลไม่มาก (< 1000)
- ไม่เหมาะ: Write-heavy, ข้อมูลมาก, Real-time requirements
เมธอดที่เกี่ยวข้อง
// จำนวนสมาชิก - O(1) int size() // เช็คว่าง - O(1) boolean isEmpty() // เช็คว่ามีสมาชิกนี้หรือไม่ - O(n) boolean contains(Object o) // Iterator - Fail-safe (Snapshot at creation time) Iterator<E> iterator() // To Array - O(n) Object[] toArray() T[] toArray(T[] a)
วิธีทดสอบ
- รันแอป ดู Set: [sai, ram, krishna, prasad]
- คลิก TextView → แสดง "Size: 4" (ไม่ใช่ 5 เพราะ "ram" ซ้ำ)
- ลองเพิ่ม "sai" อีกครั้ง → size() ยังคงเป็น 4
- ลอง remove("ram") → size() กลายเป็น 3
กรณีใช้งานจริง
- Listener/Observer Registry - เพิ่ม/ลบ Listener แบบ Thread-safe
- Whitelist/Blacklist - IP, User ID, Device ID
- Session tracking - Active sessions (Unique)
- Event bus subscribers
ทางเลือกสมัยใหม่
สำหรับ Write-heavy หรือข้อมูลมาก ควรพิจารณา:
ConcurrentHashMap.newKeySet()- Concurrent Set แบบ Lock-stripedCollections.synchronizedSet(new HashSet<>())- Simple synchronizedCopyOnWriteArraySet- เมื่อ Iteration บ่อยกว่า Modification มาก