ภาพรวมของ CopyOnWriteArrayList
CopyOnWriteArrayList เป็น List ที่ thread-safe ตัวแปรของ ArrayList ทุกครั้งที่เปลี่ยนแปลง (add, set, remove) จะสร้าง Array ใหม่ เหมาะสำหรับการอ่านมาก เขียนน้อย
ตัวอย่างการใช้งาน remove()
ตัวอย่างนี้สาธิตเมธอด remove(Object o) ซึ่งลบสมาชิก ตัวแรกที่ตรงกัน คืน true หากลบสำเร็จ
ขั้นตอนที่ 1-2: สร้างโปรเจกต์และ Layout
สร้างโปรเจกต์ใหม่ ใช้ Layout TextView
ขั้นตอนที่ 3: โค้ด Java (แก้ไข import ที่ไม่จำเป็น)
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.CopyOnWriteArrayList;
public class MainActivity extends AppCompatActivity {
CopyOnWriteArrayList<String> copyOnWriteArrayList;
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
copyOnWriteArrayList = new CopyOnWriteArrayList<>();
final TextView actionEvent = findViewById(R.id.actionEvent);
copyOnWriteArrayList.add("sai");
copyOnWriteArrayList.add("ram");
copyOnWriteArrayList.add("krishna");
copyOnWriteArrayList.add("prasad");
copyOnWriteArrayList.add("ram"); // List รับค่าซ้ำได้
actionEvent.setText("" + copyOnWriteArrayList);
actionEvent.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// ลบ "ram" ตัวแรกที่พบ
boolean removed = copyOnWriteArrayList.remove("ram");
actionEvent.setText("Removed: " + removed + " | " + copyOnWriteArrayList);
}
});
}
}
🔧 การแก้ไขจากต้นฉบับ
- ลบ import ที่ไม่ใช้:
ArrayList,ConcurrentLinkedQueue - เพิ่ม Generic Type
<String> - ปรับโค้ดแสดงผลให้ชัดเจน
CopyOnWriteArrayList vs CopyOnWriteArraySet
| คุณสมบัติ | CopyOnWriteArrayList | CopyOnWriteArraySet |
|---|---|---|
| Interface | List | Set |
| ค่าซ้ำ | ✅ อนุญาต | ❌ ห้าม |
| ลำดับ | Insertion order | Insertion order |
| remove(Object) | ลบตัวแรกที่ตรงกัน | ลบตัวเดียว (ไม่มีซ้ำ) |
| get(index) | ✅ รองรับ | ❌ ไม่รองรับ |
ตัวอย่างข้อมูล
ก่อน: [sai, ram, krishna, prasad, ram] // มี "ram" 2 ตัว
remove("ram"): ลบตัวแรกที่ index 1
หลัง: [sai, krishna, prasad, ram] // "ram" ตัวที่ 2 (index 3) เหลืออยู่
remove() variants ใน List
// ลบตัวแรกที่ตรงกับ Object (คืน boolean) boolean remove(Object o) // ลบที่ index ที่ระบุ (คืนค่าที่ลบ) E remove(int index)
⚠️ ประสิทธิภาพ
⚠️ Copy-on-write: ทุก remove() จะ สร้าง Array ใหม่ คัดลอกข้อมูลที่เหลือ O(n) เหมาะสำหรับ:
- Read-heavy, Write-rare
- Iteration พร้อม Modification (Fail-safe iterator)
- ข้อมูลขนาดเล็ก-ปานกลาง
Collections.synchronizedList() หรือ ConcurrentLinkedQueue
Fail-safe Iterator
// Iterator ไม่โยน ConcurrentModificationException
for (String item : copyOnWriteArrayList) {
// สามารถ remove() ขณะ iterate ได้ปลอดภัย
if (item.equals("ram")) {
copyOnWriteArrayList.remove(item); // Safe!
}
}
วิธีทดสอบ
- รันแอป ดู List: [sai, ram, krishna, prasad, ram]
- คลิก TextView → remove("ram") ตัวแรก
- ผลลัพธ์: [sai, krishna, prasad, ram]
- คลิกอีกครั้ง → [sai, krishna, prasad] (ลบ "ram" ตัวสุดท้าย)