Giới thiệu về remove() trong PriorityBlockingQueue
remove(Object o) xóa một lần xuất hiện của phần tử chỉ định. Trả về true nếu xóa thành công, false nếu không tìm thấy.
PriorityBlockingQueue là unbounded priority queue thread-safe. Các phần tử được sắp xếp theo thứ tự tự nhiên (Comparable) hoặc Comparator.
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.PriorityBlockingQueue;
public class MainActivity extends AppCompatActivity {
PriorityBlockingQueue<String> priorityBlockingQueue;
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
priorityBlockingQueue = new PriorityBlockingQueue<>();
final TextView actionEvent = findViewById(R.id.actionEvent);
priorityBlockingQueue.add("sai");
priorityBlockingQueue.add("ram");
priorityBlockingQueue.add("krishna");
priorityBlockingQueue.add("prasad");
priorityBlockingQueue.add("ram"); // Duplicate
actionEvent.setText("" + priorityBlockingQueue);
actionEvent.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Xóa MỘT lần xuất hiện của "prasad"
boolean removed = priorityBlockingQueue.remove("prasad");
actionEvent.setText("Đã xóa: " + removed + "\n" + priorityBlockingQueue);
}
});
}
}
Kết quả
Ban đầu (theo thứ tự alphabet): [prasad, ram, ram, sai, krishna]
Sau click remove("prasad"): [ram, ram, sai, krishna]
Lưu ý quan trọng về PriorityBlockingQueue
- Không duy trì thứ tự thêm: Tự động sắp xếp theo Comparable
- Cho phép duplicate: Không phải Set
- remove(o) xóa 1 lần xuất hiện: Nếu có 2 "ram", chỉ xóa 1
- Phức tạp O(n): Phải duyệt tìm phần tử (không phải O(log n) như heap thuần)
So sánh các phương thức xóa
| Phương thức | Hành động | Trả về | Rỗng/Không tìm thấy |
|---|---|---|---|
remove(o) |
Xóa 1 lần xuất hiện của o | boolean | false |
poll() |
Lấy VÀ xóa head (min) | E hoặc null | null |
remove() |
Lấy VÀ xóa head | E | Ném Exception |
take() |
Block lấy head | E | Block |
clear() |
Xóa tất cả | void | - |
Xóa tất cả phần tử trùng lặp
// Xóa TẤT CẢ "ram"
while (priorityBlockingQueue.remove("ram")) {
// Lặp cho đến khi không còn "ram"
}
// Hoặc dùng removeAll
priorityBlockingQueue.removeAll(Collections.singleton("ram"));
Ứng dụng thực tế - Task Cancellation
PriorityBlockingQueue<Task> taskQueue = new PriorityBlockingQueue<>(
Comparator.comparingInt(Task::getPriority)
);
// Thêm task
taskQueue.add(new Task("Download", 1));
taskQueue.add(new Task("Upload", 3));
taskQueue.add(new Task("Sync", 2));
// Hủy task cụ thể
boolean cancelled = taskQueue.remove(specificTask);
// Xử lý task theo ưu tiên
while (!taskQueue.isEmpty()) {
Task task = taskQueue.poll(); // Lấy ưu tiên cao nhất
task.execute();
}
Lưu ý
- remove(Object) dùng equals() để so sánh
- Phức tạp O(n) - không hiệu quả cho queue lớn, xóa nhiều
- Thread-safe cho đa luồng
- Không cho phép null elements