ภาพรวมของ LinkedBlockingDeque
LinkedBlockingDeque นำ Collection interface และ AbstractQueue มาใช้งาน ให้ขอบเขตตัวเลือกตามโหนดเชื่อมโยง สามารถกำหนดขนาดผ่าน Constructor
ตัวอย่างการใช้งาน removeFirstOccurrence()
ตัวอย่างนี้สาธิตเมธอด removeFirstOccurrence(Object o) ซึ่งลบสมาชิก ตัวแรกที่พบ ตรงกับค่าที่ระบุ (ค้นหาจากหัวไปท้าย) คืน true หากลบสำเร็จ
ขั้นตอนที่ 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.LinkedBlockingDeque;
public class MainActivity extends AppCompatActivity {
LinkedBlockingDeque<String> linkedBlockingDeque;
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
linkedBlockingDeque = new LinkedBlockingDeque<>();
final TextView actionEvent = findViewById(R.id.actionEvent);
linkedBlockingDeque.add("sai");
linkedBlockingDeque.add("ram");
linkedBlockingDeque.add("krishna");
linkedBlockingDeque.add("prasad");
linkedBlockingDeque.add("ram"); // "ram" ซ้ำ 2 ครั้ง
actionEvent.setText("" + linkedBlockingDeque);
actionEvent.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// ลบ "ram" ตัวแรกที่พบ (index 1)
boolean removed = linkedBlockingDeque.removeFirstOccurrence("ram");
actionEvent.setText("Removed: " + removed + " | " + linkedBlockingDeque);
}
});
}
}
พฤติกรรมของ removeFirstOccurrence()
- ค้นหาจาก หัว (head/front) ไปท้าย (tail)
- ลบ ตัวแรกที่ตรงกัน เท่านั้น
- คืน
trueหากลบสำเร็จ,falseหากไม่พบ - Thread-safe - ใช้ Lock (ReentrantLock) ภายใน
- BlockingDeque - รองรับ blocking operations ด้วย
ตัวอย่างข้อมูล
ก่อน: [sai, ram, krishna, prasad, ram]
↑
พบ "ram" ตัวแรกที่ index 1
หลัง removeFirstOccurrence("ram"): [sai, krishna, prasad, ram]
↑
"ram" ตัวที่ 2 ยังคงอยู่
removeFirstOccurrence() vs removeLastOccurrence() vs remove()
| เมธอด | คำอธิบาย | คืนค่า |
|---|---|---|
removeFirstOccurrence(o) | ลบตัวแรกที่พบ (Head→Tail) | boolean |
removeLastOccurrence(o) | ลบตัวสุดท้ายที่พบ (Tail→Head) | boolean |
remove(o) | เหมือน removeFirstOccurrence() | boolean |
removeFirst() | ลบที่หัวเสมอ (โยน Exception ถ้าว่าง) | E |
pollFirst() | นำออกที่หัว คืน null ถ้าว่าง | E |
วิธีทดสอบ
- รันแอป ดู Deque: [sai, ram, krishna, prasad, ram]
- คลิก TextView → เรียก removeFirstOccurrence("ram")
- ผลลัพธ์: [sai, krishna, prasad, ram] - "ram" ตัวแรกหายไป
- ลองเปลี่ยนเป็น removeLastOccurrence("ram") → [sai, ram, krishna, prasad]
⚠️ ข้อควรระวัง
- LinkedBlockingDeque ใช้ Lock จึงช้ากว่า ConcurrentLinkedDeque ภายใต้ Contention สูง
- หากไม่ต้องการ Blocking ให้ใช้ ConcurrentLinkedDeque
- removeFirstOccurrence() เป็น O(n) ต้องวนลูปค้นหา
กรณีใช้งานจริง
- ลบ Task เฉพาะรายการแรกที่ตรงเงื่อนไขใน Queue
- Message deduplication - ลบข้อความซ้ำตัวแรก
- Resource pool - คืน Resource ตัวแรกที่ว่าง