Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Cách sử dụng size() trong CopyOnWriteArraySet trên Android

Giới thiệu về size() trong CopyOnWriteArraySet

size() trả về số phần tử trong Set. Với CopyOnWriteArraySet, size() là O(1) vì nội bộ dùng mảng và biến count.

CopyOnWriteArraySet là Set thread-safe, không cho phép duplicate, duy trì thứ tự thêm, iterator snapshot.

Ví dụ minh họa

Bước 1: Tạo project

Android Studio → File → New Project.

Bước 2: Layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:gravity="center"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">
    <TextView
        android:id="@+id/actionEvent"
        android:textSize="40sp"
        android:layout_marginTop="30dp"
        android:layout_width="wrap_content"
        android:layout_height="match_parent" />
</LinearLayout>

Bước 3: Code (src/MainActivity.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"); // Duplicate - Set chỉ giữ 1

        actionEvent.setText("Set: " + copyOnWriteArraySet + "\nSize: " + copyOnWriteArraySet.size());

        actionEvent.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int size = copyOnWriteArraySet.size();
                actionEvent.setText("Size: " + size + "\nSet: " + copyOnWriteArraySet);
            }
        });
    }
}

Kết quả

Ban đầu: Size: 4\nSet: [sai, ram, krishna, prasad] (5 add nhưng "ram" duplicate)

Click: Size = 4

Đặc điểm CopyOnWriteArraySet

Đặc điểm Mô tả
Thread-safe Copy-on-write (ghi copy mảng mới)
Duplicate Không cho phép (Set semantics)
Thứ tự Insertion order
size() O(1) - đọc biến count
contains() O(n) - linear search mảng
add/remove O(n) - copy mảng mới
Iterator Snapshot - không ConcurrentModificationException
Cho phép null Không

So sánh size() các Set thread-safe

Set size() contains() add/remove Phù hợp
CopyOnWriteArraySet O(1) O(n) O(n) copy Read-heavy, iterator safe
ConcurrentHashMap.newKeySet() O(1) ước lượng O(1) O(1) General concurrent
Collections.synchronizedSet(HashSet) O(1) + lock O(1) + lock O(1) + lock Simple sync

Khi nào dùng CopyOnWriteArraySet

  • Listener/Observer list (ít add/remove, nhiều iterate)
  • Cần iterator an toàn tuyệt đối (snapshot)
  • Cấu hình shared, ít thay đổi
  • KHÔNG dùng cho: high-frequency updates, large sets

Ví dụ thực tế - Event Listeners

CopyOnWriteArraySet<EventListener> listeners = new CopyOnWriteArraySet<>();

// Đăng ký (ít khi xảy ra)
public void addListener(EventListener l) {
    listeners.add(l);
}

// Hủy đăng ký
public void removeListener(EventListener l) {
    listeners.remove(l);
}

// Notify (thường xuyên, an toàn iterator)
public void fireEvent(Event e) {
    for (EventListener listener : listeners) {
        // An toàn: listener có thể add/remove trong này
        listener.onEvent(e);
    }
}

Lưu ý

  • size() O(1) nhưng contains/add/remove O(n)
  • Mỗi ghi tạo mảng mới -> GC pressure nếu ghi nhiều
  • Iterator không phản ánh thay đổi real-time (snapshot)
  • Java 8+: có removeIf(Predicate) nhưng vẫn copy array