CodeGym /จาวาบล็อก /สุ่ม /ส่วนต่อประสาน Java Deque
John Squirrels
ระดับ
San Francisco

ส่วนต่อประสาน Java Deque

เผยแพร่ในกลุ่ม
Java Deque เป็นโครงสร้างข้อมูลที่รวม Queue และ Stack ธรรมดาเข้าด้วยกัน คุณสามารถเพิ่มและลบองค์ประกอบทั้งที่ส่วนหัวและส่วนท้ายของ Deque ในคิว "ดั้งเดิม" คุณเพิ่มองค์ประกอบที่ส่วนท้ายของบรรทัด (หลังองค์ประกอบสุดท้าย) และลบองค์ประกอบออกจากส่วนหัวของคิว หลักการนี้เรียกว่า First In First Out (FIFO) และใช้งานได้เหมือนสายลูกค้าทั่วไปในชีวิตจริง ใน Java Queue เป็นอินเทอร์เฟซซึ่งเป็นส่วนหนึ่งของ Collections Framework ส่วนต่อประสาน Java Deque - 1 นอกจากนี้ยังมีโครงสร้างข้อมูลสำคัญที่เรียกว่า Stack ซึ่งเป็นรายการที่ทำงานร่วมกับองค์ประกอบในหลักการย้อนกลับโดยสิ้นเชิง LIFO — เข้าก่อนออกก่อน คล้ายกับจานซ้อนกัน เพิ่มหรือเอาออกได้เฉพาะด้านบนเท่านั้น ส่วนต่อประสาน Java Deque - 2

คิว vs Deque

Deque เป็นคิวประเภทแปลก ๆ คุณสามารถเพิ่มองค์ประกอบใหม่ทั้งที่ส่วนท้ายและส่วนหัวของบรรทัด เรื่องเดียวกันกับการลบ: คุณสามารถลบองค์ประกอบสุดท้ายหรือองค์ประกอบแรกออกจากโครงสร้างนี้ได้ ดังนั้นจึงดูเหมือนว่าจะเป็นส่วนผสมของ Stack และ Queue ส่วนต่อประสาน Java Deque - 3ชื่อ “Deque” หมายถึง “Double Ended Queue” “Deque” ออกเสียงเหมือน “สำรับ” ของไพ่ และคุณรู้อะไรไหม? มันค่อนข้างคล้ายกับสำรับไพ่จริง ๆ คุณอาจหยิบไพ่จากด้านล่างหรือด้านบนของสำรับดังกล่าว ต้องการเพิ่มหรือลบองค์ประกอบจากทั้งสองด้านของโครงสร้างเชิงเส้นหรือไม่? ใช้ดีเค รองรับ Java 8 หรือเวอร์ชันอื่นเกือบทั้งหมด ลองนึกภาพตัวต่อเลโก้ทั่วไปและ "หอคอย" หนึ่งเสาที่ทำจากอิฐ คุณสามารถเพิ่มอิฐใหม่ที่ด้านบนของหอคอยหรือที่ด้านล่าง คุณยังสามารถนำก้อนอิฐออกจากทั้งสองด้านได้ เรามีตัวอย่าง: เราเพิ่มอิฐสีเหลืองทั้งหมดที่ด้านบนและสีแดงทั้งหมดที่ด้านล่าง เราจะสาธิตตัวอย่างนี้ด้วยโค้ด Java เร็วๆ นี้ ส่วนต่อประสาน Java Deque - 4คุณจึงสามารถจัดคิวและแยกออกจากปลายทั้งสองด้านของ Java Deque ได้ ซึ่งหมายความว่าคุณสามารถใช้ Deque เป็นทั้งคิวและสแต็กได้ อ่านเกี่ยวกับ Stack ใน Java: Java Stack 101: เจาะลึกเข้าไปใน Stack Class อ่านเกี่ยวกับ Queue ใน Java: Java Queue Interface และการใช้งาน

คุณสมบัติของ Deque

  • Deque ใน Java เป็นอินเทอร์เฟซซึ่งการใช้งานให้การสนับสนุนอาร์เรย์ที่ปรับขนาดได้ คุณจึงมีความสามารถมากมายที่ไร้ข้อจำกัด และคุณสามารถเพิ่มองค์ประกอบใหม่ได้ตามความต้องการของคุณ
  • Deque ไม่รองรับการเข้าถึงพร้อมกันหลายเธรด
  • Deque ไม่ปลอดภัยสำหรับเธรดในกรณีที่ไม่มีการซิงโครไนซ์ภายนอก
  • ไม่อนุญาตให้ใช้องค์ประกอบ Null ในอาร์เรย์ deque

การประกาศ Deque Java Interface


public interface Deque<E> extends Queue<E>

วิธี Java Deque

java.util.Dequeเป็นอินเทอร์เฟซที่ขยาย Java Queue Interface และแสดงถึงคิวสิ้นสุดสองครั้ง คุณจึงสามารถใช้เมธอด Java Queue ทั้งหมดได้ในขณะที่ทำงานกับ Deque แม้ว่า Deque จะไม่ขยายอินเทอร์เฟซ Stack แต่อินเทอร์เฟซ Deque จะกำหนดวิธีการที่ช่วยให้คุณสามารถดำเนินการสแต็กทั่วไปเช่น push , peekและpop
  • การเพิ่มบูลีน (องค์ประกอบ)เพิ่มองค์ประกอบที่ส่วนท้ายของ Deque คืนค่าจริงเมื่อสำเร็จ ส่ง IllegalStateException หากไม่มีที่ว่างในขณะนี้
  • addFirst(องค์ประกอบ)เพิ่มองค์ประกอบที่ส่วนหัวของ Deque
  • addLast(องค์ประกอบ)เพิ่มองค์ประกอบที่ส่วนท้ายของ Deque
  • offer(องค์ประกอบ)เพิ่มองค์ประกอบที่ส่วนท้ายและส่งกลับบูลีนเพื่ออธิบายว่าการแทรกสำเร็จหรือไม่
  • offerFirst(องค์ประกอบ)เพิ่มองค์ประกอบในส่วนหัวและส่งกลับบูลีนเพื่ออธิบายว่าการแทรกสำเร็จหรือไม่
  • offerLast(องค์ประกอบ)เพิ่มองค์ประกอบที่ส่วนท้ายและส่งกลับบูลีนเพื่ออธิบายว่าการแทรกสำเร็จหรือไม่
  • iterator()ส่งคืน iterator สำหรับ deque
  • DescendingIterator()ส่งคืนตัววนซ้ำที่มีลำดับย้อนกลับสำหรับ deque นี้
  • push(องค์ประกอบ)เพิ่มองค์ประกอบให้กับส่วนหัว
  • ป๊อป (องค์ประกอบ)ลบองค์ประกอบออกจากส่วนหัวและส่งกลับ
  • removeFirst()ลบองค์ประกอบที่ส่วนหัว
  • removeLast()ลบองค์ประกอบที่ส่วนท้าย
  • การสำรวจความคิดเห็น ()ดึงและลบส่วนหัวของคิวที่แสดงโดย deque นี้ (หรืออีกนัยหนึ่ง องค์ประกอบแรกของ deque นี้) หรือส่งคืน null หาก deque นี้ว่างเปล่า
  • pollFirst()ดึงและลบองค์ประกอบแรกของ deque นี้ หรือส่งคืน null หาก deque นี้ว่างเปล่า
  • pollLast()ดึงและลบองค์ประกอบสุดท้ายของ deque นี้ หรือส่งคืน null หาก deque นี้ว่างเปล่า
  • peek()ดึงข้อมูล แต่ไม่ลบส่วนหัวของคิวที่แสดงโดย deque นี้ (กล่าวคือองค์ประกอบแรกของ deque นี้) หรือส่งคืน null หาก deque นี้ว่างเปล่า
  • peekFirst()ดึงแต่ไม่ได้ลบ องค์ประกอบแรกของ deque นี้ หรือส่งคืนค่า null ถ้า deque นี้ว่างเปล่า
  • peekLast()ดึงแต่ไม่ได้ลบ องค์ประกอบสุดท้ายของ deque นี้ หรือคืนค่า null ถ้า deque นี้ว่างเปล่า
ในตารางด้านล่างวิธีการทั้งหมดจะถูกแบ่งตามกลุ่ม อย่างที่คุณเห็นมีหลายวิธีในการเพิ่มและลบองค์ประกอบ ตัวอย่างเช่น ทั้ง removeFirst() และ pop() จะลบองค์ประกอบแรกออกจาก deque อันที่สอง "มา" จากสแต็ก นั่นหมายความว่า หากคุณใช้ ArrayDeque เป็นสแต็กเท่านั้น ให้ใช้ pop() เพื่อลบ, push() เพื่อเพิ่ม และ peek() เพื่อตรวจสอบ สิ่งนี้ทำให้โค้ดของคุณเหมาะสมสำหรับนักพัฒนารายอื่น
องค์ประกอบแรก (หัว) องค์ประกอบสุดท้าย (หาง)
การดำเนินการ โยนข้อยกเว้น ค่าพิเศษ โยนข้อยกเว้น ค่าพิเศษ
การแทรก addFirst(e)/push(e) offerFirst(จ) addLast(จ) offerLast()
ลบ ลบครั้งแรก () / ป๊อป () การสำรวจความคิดเห็นครั้งแรก () ลบล่าสุด () แบบสำรวจล่าสุด ()
พิจารณา รับครั้งแรก () peekFirst()/มอง() รับสุดท้าย () peekLast()

การใช้งาน Deque

Java Deque เป็นอินเทอร์เฟซและมีการใช้งานใน Java Collections API:
  • java.util.LinkedList // แสดงรายการและใช้งาน Deque
  • java.util.ArrayDeque // การใช้งาน Deque ไลบรารี Java
ส่วนต่อประสาน Java Deque - 5คลาส LinkedList ใช้รายการที่เชื่อมโยงสองครั้งภายในเพื่อสร้างแบบจำลองคิวหรือ deque คลาส ArrayDeque เก็บองค์ประกอบภายในอาร์เรย์ หากจำนวนขององค์ประกอบเกินปริมาณของอาร์เรย์ จะมีการจัดสรรอาร์เรย์ใหม่ และองค์ประกอบทั้งหมดจะย้ายไป นั่นหมายความว่า ArrayDeque เติบโตตามความต้องการ

คลาส ArrayDeque

คลาส ArrayDeque <E>เป็นคิวสองทิศทางทั่วไป สืบทอดการทำงานจากคลาส AbstractCollection และใช้อินเทอร์เฟซ Deque ArrayDeque อำนวยความสะดวกในการใช้ deque และอาร์เรย์ที่ปรับขนาดได้ ในขั้นต้น อาร์เรย์เริ่มต้นด้วยขนาด 16 มันถูกนำไปใช้เป็นคิวแบบสองทาง ซึ่งรองรับพอยน์เตอร์สองตัว ได้แก่ ส่วนหัวและส่วนท้าย มันสืบทอด คลาส AbstractCollectionและใช้อินเทอร์เฟซDeque ประเด็นสำคัญเกี่ยวกับคลาส ArrayDeque คือ:
  • คุณสามารถเพิ่มหรือลบองค์ประกอบจากส่วนท้ายและส่วนหัวของ ArrayDeque
  • ไม่อนุญาตให้ใช้องค์ประกอบ Null
  • ArrayDeque ไม่ปลอดภัยสำหรับเธรดในกรณีที่ไม่มีการซิงโครไนซ์ภายนอก
  • ArrayDeque ไม่มีข้อจำกัดด้านความจุ

ตัวสร้างคลาส ArrayDeque

  • ArrayDeque()สร้างคิวว่าง
  • ArrayDeque (คอลเลกชัน <? ขยาย E> คอลเลกชัน)สร้างคิวที่เต็มไปด้วยองค์ประกอบคอลเลกชันคอลเลกชัน
  • ArrayDeque (ความจุ int)สร้างคิวที่มีความจุ เริ่มต้น หากคุณไม่ระบุความจุเริ่มต้น ความจุเริ่มต้นคือ 16

ตัวอย่าง Java Deque — ArrayDeque

จำตัวอย่าง Lego Tower จากจุดเริ่มต้นของบทความได้หรือไม่? มาสร้างชั้นเรียนเพื่อสร้างหอคอยแบบเสาเดียวที่ทำจากเลโก้บริคกันเถอะ อิฐสามารถเป็นสีแดง สีเหลือง หรือสีน้ำเงิน กฎการสร้างหอคอยของเรา: เราวางอิฐสีแดงที่ด้านล่างและอิฐสีเหลืองที่ด้านบน ตัวอย่าง Big Java Deque

//enum with colors 
public enum Color {
   RED, YELLOW, BLUE;
}

//class for the standard Lego Brick. You can connect or disconnect the Brick, it has color   
public class LegoBrick {
   Color color;
   boolean isConnected;

   public void connect() {
       System.out.println("This brick is connected");
       this.isConnected = true;
   }

   public void disconnect() {
       System.out.println("Disconnected");
       isConnected = false;
   }

   public LegoBrick(Color color, boolean isConnected) {
       this.color = color;
       this.isConnected = isConnected;
   }

   public Color getColor() {
       return color;
   }

   public boolean isConnected() {
       return isConnected;
   }

   @Override
   public String toString() {
       return "LegoBrick{" +
              "color=" + color +
              ", isConnected=" + isConnected +
              '}';
   }
}
นี่คือชั้นทาวเวอร์ของเรา เราเริ่มต้นหอคอย หอคอยเริ่มต้นขึ้นอยู่กับปริมาณของสีแดงและสีเหลือง เราสามารถเพิ่มอิฐเข้าไปในหอคอยหรือเอาออกได้ เราเพิ่มอิฐที่ด้านบนหากเป็นสีเหลืองและเพิ่มที่ด้านล่างหากเป็นสีแดง

import java.util.ArrayDeque;
public class LegoTower {
   ArrayDeque<LegoBrick> myTower;
   int quantityOfReds;
   int quantityOfYellows;

   public void addBrickToTower(LegoBrick newLegoBrick) {
       if (newLegoBrick.getColor() == Color.YELLOW) {
           this.myTower.offerLast(newLegoBrick);
           quantityOfYellows++;
       }
	//we can use addFirst(e)/push(e) instead of offerFirst here 
       if (newLegoBrick.getColor() == Color.RED) {
           myTower.offerFirst(newLegoBrick);
           quantityOfReds++;
       }
   }

   public void removeBrickFromTower (LegoBrick legoBrick) {
       if (legoBrick.getColor() == Color.YELLOW) {
           this.myTower.removeLast();
           quantityOfYellows--;
       }
       if (legoBrick.getColor() == Color.RED) {
           myTower.removeFirst();
           quantityOfReds--;
       }
       legoBrick.isConnected = false;

   }

   public LegoTower(int quantityOfReds, int quantityOfYellows) {

       myTower = new ArrayDeque<>();
       this.quantityOfReds = quantityOfReds;
       this.quantityOfYellows = quantityOfYellows;
       for (int i = 0; i < quantityOfReds; i++) {
           LegoBrick redLegoBrick = new LegoBrick(Color.RED, false);
           myTower.addFirst(redLegoBrick);
           redLegoBrick.isConnected = true;
       }
       for (int i = 0; i < quantityOfYellows; i++) {
           LegoBrick yellowLegoBrick = new LegoBrick(Color.YELLOW, false);
           myTower.addLast(yellowLegoBrick);
           yellowLegoBrick.isConnected = true;
       }
   }

   public void setMyTower(ArrayDeque<legobrick> myTower) {
       this.myTower = myTower;
   }

   public void setQuantityOfReds(int quantityOfReds) {
       this.quantityOfReds = quantityOfReds;
   }

   public void setQuantityOfYellows(int quantityOfYellows) {
       this.quantityOfYellows = quantityOfYellows;
   }

   @Override
   public String toString() {
       return "LegoTower{" +
              "myTower=" + myTower +
              ", quantityOfReds=" + quantityOfReds +
              ", quantityOfYellows=" + quantityOfYellows +
              '}';
   }

   public void drawTower() {
       for (LegoBrick i : myTower) {
           System.out.println(i.color);
       }
   }
}


public class Main {
   public static void main(String[] args) {
       LegoBrick legoBrick1 = new LegoBrick(Color.YELLOW, false);
       legoBrick1.connect();
       System.out.println(legoBrick1.toString());
       legoBrick1.disconnect();
       System.out.println(legoBrick1.toString());
       LegoBrick legoBrick2 = new LegoBrick(Color.YELLOW, false);
       LegoBrick legoBrick3 = new LegoBrick(Color.RED, false);
       LegoBrick legoBrick4 = new LegoBrick(Color.RED, false);
       LegoBrick legoBrick5 = new LegoBrick(Color.YELLOW, false);

       LegoTower legoTower = new LegoTower(2, 5);
       System.out.println("my Initiated Lego Tower: ");
       legoTower.drawTower();
       legoTower.addBrickToTower(legoBrick1);
       legoTower.addBrickToTower(legoBrick2);
       legoTower.addBrickToTower(legoBrick3);
       legoTower.addBrickToTower(legoBrick4);
       legoTower.addBrickToTower(legoBrick5);
       System.out.println("My LegoTower after adding some elements: ");
       legoTower.drawTower();
       legoTower.removeBrickFromTower(legoBrick1);
       legoTower.removeBrickFromTower(legoBrick3);
       System.out.println("We removed one red and one yellow brick:");
       legoTower.drawTower();

   }

}
ผลลัพธ์ของการเรียกใช้โปรแกรมนี้:

my Initiated LegoTower:

RED
RED
YELLOW
YELLOW
YELLOW
YELLOW
YELLOW
My LegoTower after adding some elements: 
RED
RED
RED
RED
YELLOW
YELLOW
YELLOW
YELLOW
YELLOW
YELLOW
YELLOW
YELLOW
We removed one red and one yellow brick:
RED
RED
RED
YELLOW
YELLOW
YELLOW
YELLOW
YELLOW
YELLOW
YELLOW

Process finished with exit code 0
รออะไร?? ทำไมสีแดงถึงอยู่ข้างบน? ไม่พวกเขาไม่ พวกเขาเพิ่งพิมพ์ไปที่คอนโซลโดยเริ่มจากอันแรก (ล่าง) ถึงอันสุดท้าย (บนสุด) ดังนั้นหากคุณต้องการเห็นบางอย่างเช่นในภาพที่มีตัวต่อด้านบน คุณอาจเปลี่ยนวิธีการวาด Tower ของคลาส LegoTower มันเป็นงานที่ง่ายมาก!

รายการที่เชื่อมโยง

ส่วนต่อประสานรายการจะรักษาลำดับของการเพิ่มรายการและอนุญาตให้เข้าถึงรายการด้วยดัชนี Deque เป็นคิวแบบสองทางและรองรับการเพิ่มและลบองค์ประกอบจากทั้งสองด้าน ส่วนต่อประสาน Java Deque - 6LinkedList เป็นที่รู้จักกันโดยทั่วไปว่าเป็นการใช้งาน List แต่คลาสนี้ยังใช้ Deque และช่วยให้เราสามารถสร้างคิวแบบสองทิศทางที่ประกอบด้วยวัตถุใด ๆ รวมถึง null LinkedList คือชุดขององค์ประกอบต่างๆ เราสามารถเห็นได้ในซอร์สโค้ดของคลาส คราวนี้ให้ความสนใจกับฟิลด์: ที่นี่ เราเพิ่มหนึ่งตัวอย่าง แต่ถ้าคุณต้องการเรียนรู้เพิ่มเติมเกี่ยวกับ LinkedList ยินดีต้อนรับสู่บทความCodeGymนี้

การใช้งานรายการที่เชื่อมโยงใน Java การเพิ่มและลบองค์ประกอบ ตัวอย่าง

ลองดำเนินการเหล่านี้ในทางปฏิบัติ อันดับแรก การใช้งาน Java LinkedList: การสร้าง LinkedList ของ Strings โดยเพิ่มองค์ประกอบ 3 รายการ จากนั้นเอาอันหนึ่งออก แล้วเพิ่มอันหนึ่งตรงกลาง

public class MyLinkedTest {
   public static void main(String[] args) {
       String h1 = "my";
       String h2 = "favorite";
       String h3 = "book";
//  LinkedList implementation in Java
       LinkedList<string> linkedList = new LinkedList();
       linkedList.add(h1);
       linkedList.add(h2);
       linkedList.add(h3);
       System.out.println("my list after adding 3 elements:");
       System.out.println(linkedList);
       System.out.println("element #2 of my list:");
       System.out.println(linkedList.get(2));
       linkedList.remove(1);
       System.out.println("my list after removing #1:");
       System.out.println(linkedList);
       linkedList.add(1,"first");
       System.out.println("my list after adding an element in the middle");
       System.out.println(linkedList);
   }
ผลลัพธ์ของการเรียกใช้โปรแกรมนี้:

my list after adding 3 elements:
[my, favorite, book]
element #2 of my list:
book
my list after removing #1:
[my, book]
my list after adding an element in the middle
[my, first, book]
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION