Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Android

วิธีใช้ size() ใน CopyOnWriteArraySet ของ Android

ภาพรวมของ 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

คุณสมบัติCopyOnWriteArraySetCopyOnWriteArrayList
size() ComplexityO(1)O(1)
Duplicate❌ ไม่ได้✅ ได้
get(index)❌ ไม่มี✅ มี
contains()O(n) - Linear searchO(n) - Linear search
Add/RemoveO(n) - Copy arrayO(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)

วิธีทดสอบ

  1. รันแอป ดู Set: [sai, ram, krishna, prasad]
  2. คลิก TextView → แสดง "Size: 4" (ไม่ใช่ 5 เพราะ "ram" ซ้ำ)
  3. ลองเพิ่ม "sai" อีกครั้ง → size() ยังคงเป็น 4
  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-striped
  • Collections.synchronizedSet(new HashSet<>()) - Simple synchronized
  • CopyOnWriteArraySet - เมื่อ Iteration บ่อยกว่า Modification มาก