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

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

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

remove(Object o) xóa phần tử chỉ định khỏi Set. Trả về true nếu phần tử tồn tại và bị xóa, false nếu không tìm thấy.

CopyOnWriteArraySet tạo bản sao mảng mới mỗi lần ghi - thread-safe, iterator snapshot, phù hợp read-heavy.

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 - chỉ giữ 1

        actionEvent.setText("" + copyOnWriteArraySet);

        actionEvent.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Xóa "ram" khỏi Set
                boolean removed = copyOnWriteArraySet.remove("ram");
                actionEvent.setText("Đã xóa: " + removed + "\n" + copyOnWriteArraySet);
            }
        });
    }
}

Kết quả

Ban đầu (Set unique): [sai, ram, krishna, prasad]

Sau click remove("ram"): [sai, krishna, prasad]

Đặc điểm CopyOnWriteArraySet

Đặc điểm Mô tả
Thread-safe Copy-on-write (mọi ghi copy mảng mới)
Không cho phép duplicate Set semantics
Iterator Snapshot - không bao giờ ConcurrentModificationException
Cho phép null Không
Thứ tự Thứ tự thêm (insertion order)
Phức tạp add/remove O(n) - copy mảng
Phức tạp contains O(n) - linear search

So sánh remove() các Collection

Collection remove(o) Thread-safe Hiệu năng
CopyOnWriteArraySet O(n) copy array Copy-on-write Ghi chậm, đọc nhanh
HashSet O(1) trung bình Không Nhanh nhất single-thread
ConcurrentHashMap.newKeySet() O(1) trung bình Lock-free/CAS Cân bằng đọc/ghi
Collections.synchronizedSet() O(1) + lock Synchronized Lock contention cao

Iterator an toàn - Điểm mạnh lớn nhất

CopyOnWriteArraySet<String> set = new CopyOnWriteArraySet<>();
set.add("A"); set.add("B"); set.add("C");

// Duyệt an toàn - có thể remove trong loop
for (String s : set) {
    if (s.equals("B")) {
        set.remove("B"); // KHÔNG ném ConcurrentModificationException
    }
}
// Iterator thấy snapshot tại thời điểm tạo: [A, B, C]

Khi nào dùng CopyOnWriteArraySet?

  • Listener/Observer pattern (đăng ký ít, notify nhiều)
  • Cấu hình shared config (ít thay đổi)
  • Cần iterator an toàn tuyệt đối
  • KHÔNG dùng cho: high-frequency updates, real-time, big data

Lưu ý

  • Mỗi remove() tạo mảng mới - tốn GC nếu xóa nhiều
  • Dùng removeAll() cho batch remove hiệu quả hơn
  • Không có removeIf() (Java 8+) - cần tự implement