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

Cách dùng subList() trong CopyOnWriteArrayList Android

CopyOnWriteArrayList và subList()

CopyOnWriteArrayList là biến thể thread-safe của ArrayList. Mọi phép ghi (add, set, remove...) tạo bản sao mới của mảng nội bộ. Phù hợp khi đọc nhiều, ghi ít.

Phương thức subList(int fromIndex, int toIndex) trả về view của phần tử từ fromIndex (inclusive) đến toIndex (exclusive).

Bước 1: Tạo dự án mới

Khởi tạo project Android Studio.

Bước 2: Layout (res/layout/activity_main.xml)

<?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:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/actionEvent"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_marginTop="30dp"
        android:textSize="30sp" />

</LinearLayout>

Bước 3: 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.CopyOnWriteArrayList;

public class MainActivity extends AppCompatActivity {
    private CopyOnWriteArrayList<String> copyOnWriteArrayList;
    private TextView actionEvent;
    
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        copyOnWriteArrayList = new CopyOnWriteArrayList<>();
        actionEvent = findViewById(R.id.actionEvent);
        
        copyOnWriteArrayList.add("sai");
        copyOnWriteArrayList.add("ram");
        copyOnWriteArrayList.add("krishna");
        copyOnWriteArrayList.add("prasad");
        copyOnWriteArrayList.add("ram"); // Cho phép trùng lặp (khác với Set)
        
        actionEvent.setText("Full list: " + copyOnWriteArrayList);
        
        actionEvent.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // subList(0, 2) -> index 0, 1 (2 phần tử đầu)
                actionEvent.setText("subList(0,2): " + copyOnWriteArrayList.subList(0, 2));
            }
        });
    }
}

Kết quả

Ban đầu: [sai, ram, krishna, prasad, ram]

Sau click: [sai, ram] (2 phần tử đầu tiên)

Đặc điểm quan trọng của subList()

  • Trả về view (view), không phải copy: Thay đổi qua subList ảnh hưởng list gốc và ngược lại
  • fromIndex inclusive, toIndex exclusive
  • Ném IndexOutOfBoundsException nếu index không hợp lệ
  • Hỗ trợ tất cả operation của List (add, remove, set... trên subList)

Ví dụ thao tác trên subList

List<String> sub = copyOnWriteArrayList.subList(1, 4); // [ram, krishna, prasad]

sub.clear(); // Xóa 3 phần tử giữa
// copyOnWriteArrayList giờ thành: [sai, ram]

sub.add("new"); // Thêm vào giữa
// copyOnWriteArrayList: [sai, new, ram]

Lưu ý hiệu năng

  • Mọi thay đổi trên subList (add/remove/set) đều trigger copy toàn bộ mảng nội bộ của CopyOnWriteArrayList gốc
  • Nên tránh sửa đổi lớn trên subList của CopyOnWriteArrayList
  • Chỉ dùng subList để đọc hoặc duyệt (iterate)

So sánh với ArrayList thường

Đặc điểm ArrayList CopyOnWriteArrayList
Thread-safe Không Có
subList behavior View (linked) View (linked)
Chi phí ghi O(1) amortized O(n) - copy mảng
Iterator Fail-fast Snapshot (không bao giờ ConcurrentModificationException)

Khi nào dùng CopyOnWriteArrayList?

  • Danh sách listener/observer (đăng ký/hủy ít, duyệt nhiều)
  • Cache dữ liệu ít khi cập nhật
  • Cần iterator an toàn khi có thread khác sửa đổi