الطابور في جافا هو واجهة متوفرة في حزمة java.util وتمتد واجهة جافا القائمة. تمامًا مثل قائمة جافا، طابور جافا هو مجموعة من العناصر المرتبة (أو الكائنات) ولكنه يقوم بإجراء عمليات الإدراج والإزالة بشكل مختلف. يمكننا استخدام الطابور لتخزين العناصر قبل معالجة تلك العناصر.
طابور جافا
في هذا القسم، سنناقش بعض النقاط المهمة حول طابور جافا:
- واجهة java.util.Queue هي نوع فرعي من واجهة java.util.Collection.
- تمامًا مثل الطابور في العالم الحقيقي (على سبيل المثال، في البنك أو في جهاز الصراف الآلي)، يُدخل الطابور العناصر في نهاية الطابور ويُزيل من بداية الطابور.
- يمثل طابور جافا قائمة مرتبة من العناصر.
- يتبع طابور جافا ترتيب FIFO لإدراج وإزالة عناصره. FIFO تعني الدخول أولاً، الخروج أولاً.
- تدعم طابور جافا جميع أساليب واجهة الجمع.
- أكثر تنفيذات طابور المستخدمة بشكل متكرر هي LinkedList، ArrayBlockingQueue وPriorityQueue.
- لا تقبل BlockingQueues العناصر الفارغة. إذا قمنا بأي عملية متعلقة بالقيمة الفارغة، فإنه يرمي استثناء القيمة الفارغة.
- يتم استخدام BlockingQueues لتنفيذ تطبيقات المنتج/المستهلك.
- BlockingQueues آمنة من الناحية الأمنية.
- جميع قوائم الانتظار المتاحة في حزمة java.util هي قوائم انتظار غير محدودة والقوائم التي تتوفر في حزمة java.util.concurrent هي قوائم انتظار محدودة.
- جميع القوائم غير الخطية ليست آمنة للتعداد.
- ConcurrentLinkedQueue هو قائمة انتظار غير محدودة وآمنة للتعداد تعتمد على توصيل العقد.
- جميع القوائم تدعم إدخال عنصر في ذيل القائمة وإزالة عنصر من رأس القائمة، باستثناء القوائم غير الخطية.
- القوائم غير الخطية هي قوائم انتظار ولكنها تدعم إدخال العناصر وإزالتها من كلا الطرفين.
مخطط فئة قائمة الجافا
واجهة قائمة الجافا تمتد من واجهة تجميع. واجهة التجميع تمتد من واجهة Iterable. بعض فئات تنفيذ قائمة الجافا المستخدمة بشكل متكرر هي LinkedList وPriorityQueue وArrayBlockingQueue وDelayQueue وLinkedBlockingQueue وPriorityBlockingQueue وغيرها… AbstractQueue يوفر تنفيذًا هيكليًا لواجهة قائمة الانتظار لتقليل الجهد في تنفيذ قائمة الانتظار.
طرق قائمة الجافا
في هذا القسم سنناقش بعض طرق قائمة الجافا المفيدة والمستخدمة بشكل متكرر:
- int size(): للحصول على عدد العناصر في المجموعة.
- boolean isEmpty(): للتحقق ما إذا كانت المجموعة فارغة أم لا.
- boolean contains(Object o): يُرجع القيمة true إذا كانت هذه المجموعة تحتوي على العنصر المحدد.
- Iterator iterator(): يُرجع محدد العناصر في هذه المجموعة. يتم إرجاع العناصر بترتيب عشوائي.
- boolean removeAll(Collection c): يقوم بإزالة جميع العناصر التي تحتويها هذه المجموعة والتي تم تضمينها في المجموعة المحددة (عملية اختيارية).
- boolean retainAll(Collection c): يحتفظ فقط بالعناصر في هذه المجموعة التي تم تضمينها في المجموعة المحددة (عملية اختيارية).
- void clear(): يُزيل جميع العناصر من المجموعة.
- E remove(): Retrieves and removes the head of this queue.
- E poll(): Retrieves and removes the head of this queue, or returns null if this queue is empty.
- E peek(): Retrieves, but does not remove, the head of this queue, or returns null if this queue is empty.
- boolean offer(E e): يُدرج العنصر المحدد في هذه الطابور إذا كان من الممكن القيام بذلك فورًا دون خرق القيود السعة.
- E element(): Retrieves, but does not remove, the head of this queue.
- boolean add(E e): يُدرج العنصر المحدد في هذه الطابور إذا كان من الممكن القيام بذلك فورًا دون خرق القيود السعة، ويعيد القيمة true في حال نجاح العملية ويُطلق استثناء IllegalStateException إذا لم يتوفر مساحة حاليًا.
- Object[] toArray(): يُرجع مصفوفة تحتوي على جميع العناصر في هذه المجموعة. إذا كانت هذه المجموعة تضمن أي ضمانات بشأن ترتيب عناصرها التي تُرجعها محددتها، يجب أن تعيد هذه الطريقة العناصر بنفس الترتيب.
أساسيات طابور جافا
كما أن Java Queue يمتد من Java Collection ، فإنه يدعم أيضًا جميع عمليات واجهة Collection. دعونا نستكشف بعض العمليات البسيطة في المثال التالي:
package com.journaldev.queue;
import java.util.*;
public class QueueExample {
public static void main(String[] args) {
Queue queue = new LinkedList<>();
queue.add("one");
queue.add("two");
queue.add("three");
queue.add("four");
System.out.println(queue);
queue.remove("three");
System.out.println(queue);
System.out.println("Queue Size: " + queue.size());
System.out.println("Queue Contains element 'two' or not? : " + queue.contains("two"));
// لتفريغ الطابور
queue.clear();
}
}
الإخراج:-
[one, two, three, four]
[one, two, four]
Queue Size: 3
Queue Contains element 'two' or not? : true
Java Array to Queue
هنا يمكننا استكشاف كيفية تحويل مصفوفة Java إلى طابور باستخدام طريقة “Collections.addAll()” بمثال بسيط.
import java.util.*;
public class ArrayToQueue {
public static void main(String[] args) {
String nums[] = {"one","two","three","four","five"};
Queue<String> queue = new LinkedList<>();
Collections.addAll(queue, nums);
System.out.println(queue);
}
}
الإخراج:- عند تشغيل البرنامج أعلاه، سنحصل على الإخراج التالي:
[one, two, three, four, five]
Java Queue to Array
هنا سنستكشف كيفية تحويل طابور Java إلى مصفوفة Java باستخدام “toArray()” مع مثال بسيط.
import java.util.*;
public class QueueToArray {
public static void main(String[] args) {
Queue<String> queue = new LinkedList<>();
queue.add("one");
queue.add("two");
queue.add("three");
queue.add("four");
queue.add("five");
String strArray[] = queue.toArray(new String[queue.size()]);
System.out.println(Arrays.toString(strArray));
}
}
الإخراج:- عند تشغيل البرنامج أعلاه، سنحصل على الإخراج التالي:
[one, two, three, four, five]
Java Queue Common Operations
يدعم Java Queue جميع العمليات المدعومة بواجهة Collection وبعض العمليات الإضافية. يدعم تقريبًا جميع العمليات بشكلين.
- مجموعة واحدة من العمليات تُثير استثناءً إذا فشلت العملية.
- مجموعة العمليات الأخرى تعيد قيمة خاصة إذا فشلت العملية.
الجدول التالي يشرح جميع العمليات الشائعة في قائمة الانتظار بشكل موجز.
Operation | Throws exception | Special value |
---|---|---|
Insert | add(e) | offer(e) |
Remove | remove() | poll() |
Examine | element() | peek() |
سنتناول كل عملية ونناقشها بالتفصيل مع بعض الأمثلة المفيدة في الأقسام المقبلة.
عمليات إدراج قائمة الانتظار في جافا
في هذا القسم، سنناقش عملية إدراج قائمة الانتظار في جافا بالتفصيل مع بعض الأمثلة المفيدة. إذا تم تنفيذ هذه العملية بنجاح، فإنها تعيد قيمة “صحيح”. كما نعلم، تدعم قائمة الانتظار عملية الإدراج بشكلين:
- Queue.add(e):
إنه يثير استثناءً إذا فشلت العملية.- Queue.offer(e):
إنها تعيد قيمة خاصة إذا فشلت العملية.
ملاحظة:- قد تكون القيمة الخاصة إما “غير صحيحة” أو “فارغة”
عملية add() في قائمة الانتظار
تُستخدم عملية add() لإدراج عنصر جديد في قائمة الانتظار. إذا تم تنفيذ عملية الإدراج بنجاح، فإنها تعيد قيمة “صحيح”. وإلا، فإنها تثير استثناء java.lang.IllegalStateException. دعنا نقوم بتطوير مثال بسيط لتوضيح هذه الوظيفة.
import java.util.concurrent.*;
public class QueueAddOperation {
public static void main(String[] args) {
BlockingQueue<String> queue = new ArrayBlockingQueue<>(2);
System.out.println(queue.add("one"));
System.out.println(queue.add("two"));
System.out.println(queue);
System.out.println(queue.add("three"));
System.out.println(queue);
}
}
الإخراج:- عند تشغيل البرنامج أعلاه، سنحصل على الإخراج التالي:
true
true
[one, two]
Exception in thread "main" java.lang.IllegalStateException: Queue full
نظرًا لأن قائمتنا محدودة إلى عنصرين، عند محاولة إضافة عنصر ثالث باستخدام BlockingQueue.add()، يُثير استثناء كما هو موضح أعلاه.
عملية العرض في القائمة
تُستخدم عملية العرض ()لإدراج عنصر جديد في القائمة. إذا نفذت عملية الإدراج بنجاح، فإنها تعيد قيمة “صحيح”. وإلا فإنها تعيد قيمة “خطأ”. دعونا نقدم مثالًا بسيطًا لتوضيح هذه الوظيفة.
import java.util.concurrent.*;
public class QueueOfferOperation {
public static void main(String[] args) {
BlockingQueue<String> queue = new ArrayBlockingQueue<>(2);
System.out.println(queue.offer("one"));
System.out.println(queue.offer("two"));
System.out.println(queue);
System.out.println(queue.offer("three"));
System.out.println(queue);
}
}
الإخراج:- عند تشغيل البرنامج أعلاه، سنحصل على الإخراج التالي:
true
true
[one, two]
false
[one, two]
نظرًا لأن قائمتنا محدودة إلى عنصرين، عند محاولة إضافة عنصر ثالث باستخدام عملية BlockingQueue.offer()، تعيد العملية قيمة “خطأ” كما هو موضح أعلاه.
عمليات حذف قائمة Java
في هذا القسم، سنناقش عن عمليات حذف قائمة Java بتفصيل مع بعض الأمثلة المفيدة. تعيد عمليات الحذف العنصر الأول في القائمة، إذا تم تنفيذها بنجاح. كما نعلم، تدعم القائمة عملية الحذف بشكلين:
- Queue.remove():
يُثير استثناء إذا فشلت العملية.- Queue.poll():
تعيد قيمة خاصة إذا فشلت العملية.
ملاحظة:- هنا قد تكون القيمة الخاصة إما “false” أو “null”
عملية إزالة الطابور
تُستخدم عملية remove() لحذف عنصر من رأس الطابور. إذا نجحت عملية الحذف، فإنها تعيد عنصر رأس الطابور. وإلا، فإنها تطلق java.util.NoSuchElementException. دعنا نطور مثالًا بسيطًا لتوضيح هذه الوظيفة.
import java.util.*;
public class QueueRemoveOperation
{
public static void main(String[] args)
{
Queue<String> queue = new LinkedList<>();
queue.offer("one");
queue.offer("two");
System.out.println(queue);
System.out.println(queue.remove());
System.out.println(queue.remove());
System.out.println(queue.remove());
}
}
الناتج:- عند تشغيل البرنامج أعلاه، سنحصل على الناتج التالي:
[one, two]
one
two
Exception in thread "main" java.util.NoSuchElementException
نظرًا لأن طابورنا يحتوي فقط على عنصرين، عند محاولتنا استدعاء طريقة remove() للمرة الثالثة، فإنها تطلق استثناءً كما هو موضح أعلاه. ملاحظة:- يُستخدم Queue.remove(element) لحذف عنصر محدد من الطابور. إذا نجحت عملية الحذف، فإنها تعيد قيمة “true”. وإلا، فإنها تعيد قيمة “false”.
عملية الانتظار في الطابور
تُستخدم عملية poll() لحذف عنصر من رأس الطابور. إذا نجحت عملية الحذف، فإنها تعيد عنصر رأس الطابور. وإلا، فإنها تعيد قيمة “null”. دعنا نطور مثالًا بسيطًا لتوضيح هذه الوظيفة.
import java.util.*;
public class QueuePollOperation
{
public static void main(String[] args)
{
Queue<String> queue = new LinkedList<>();
queue.offer("one");
queue.offer("two");
System.out.println(queue);
System.out.println(queue.poll());
System.out.println(queue.poll());
System.out.println(queue.poll());
}
}
الناتج:- عند تشغيل البرنامج أعلاه، سنحصل على الناتج التالي:
[one, two]
one
two
null
نظرًا لأن قائمتنا تحتوي فقط على عنصرين، عند محاولة استدعاء طريقة poll() للمرة الثالثة، تعيد قيمة فارغة كما هو موضح أعلاه.
عمليات فحص قائمة الانتظار في جافا
في هذا القسم، سنناقش عمليات فحص قائمة الانتظار في جافا بتفصيل مع بعض الأمثلة المفيدة. إذا نجحت هذه العملية بنجاح، فإنها تعيد عنصر الرأس من قائمة الانتظار دون إزالته. كما نعلم، تدعم قائمة الانتظار عملية الفحص بشكلين:
- Queue.element():
تقوم برمي استثناء إذا فشلت العملية.- Queue.peek():
تعيد قيمة خاصة إذا فشلت العملية.
ملاحظة:- هنا يمكن أن تكون القيمة الخاصة إما “خطأ” أو “فارغة”
عملية عنصر قائمة الانتظار
تُستخدم عملية element() لاسترداد عنصر من رأس قائمة الانتظار، دون إزالته. إذا نجحت العملية بنجاح، فإنها تعيد عنصر الرأس من قائمة الانتظار. وإلا فإنها تُلقي java.util.NoSuchElementException. دعونا نقوم بتطوير مثال بسيط لتوضيح هذه الوظيفة.
import java.util.*;
public class QueueElementOperation {
public static void main(String[] args) {
Queue<String> queue = new LinkedList<>();
queue.add("one");
System.out.println(queue.element());
System.out.println(queue);
queue.clear();
System.out.println(queue.element());
}
}
الناتج:- عند تشغيل البرنامج أعلاه، سنحصل على الناتج التالي:
one
[one]
Exception in thread "main" java.util.NoSuchElementException
إذا حاولنا استدعاء طريقة element() على Queue فارغ، فإنه يقذف استثناء كما هو موضح أعلاه.
عملية peek() في Queue
تستخدم عملية peek() لاسترجاع عنصر من رأس الطابور دون إزالته. إذا نفذت العملية بنجاح، فإنها تعيد عنصر رأس الطابور. وإلا، فإنها تعيد قيمة فارغة. دعونا نقدم مثالًا بسيطًا لتوضيح هذه الوظيفة.
import java.util.*;
public class QueuePeekOperation {
public static void main(String[] args) {
Queue<String> queue = new LinkedList<>();
queue.add("one");
System.out.println(queue.peek());
System.out.println(queue);
queue.clear();
System.out.println(queue.peek());
}
}
الإخراج:-عند تشغيل البرنامج أعلاه، سنحصل على الإخراج التالي:
one
[one]
null
إذا حاولنا استدعاء طريقة peek() على Queue فارغ، فإنه يعيد قيمة فارغة، ولكن لا يقذف استثناء كما هو موضح أعلاه.
فئات Queue في Java
في لغة Java، يمكننا العثور على العديد من تنفيذات Queue. يمكننا تصنيفها عمومًا إلى الأنواع التالية
- Queues محدودة الحجم
- Queues غير محدودة الحجم
الطوابير المحدودة هي طوابير محدودة بواسطة القدرة ، وهذا يعني أنه يجب علينا توفير الحجم الأقصى للطابور في وقت الإنشاء. على سبيل المثال ، ArrayBlockingQueue (انظر المثال السابق). الطوابير غير المحدودة هي طوابير لا تحد بسعة ، وهذا يعني أنه يجب علينا عدم توفير حجم الطابور. على سبيل المثال LinkedList (انظر المثال السابق). جميع الطوابير المتاحة في حزمة java.util هي طوابير غير محدودة والطوابير المتاحة في حزمة java.util.concurrent هي طوابير محدودة. بطرق أخرى ، يمكننا تصنيفها عمومًا إلى نوعين التاليين:
- الطوابير القابلة للحجز
- الطوابير غير القابلة للحجز
جميع الطوابير التي تنفذ واجهة BlockingQueue هي طوابير قابلة للحجز والباقي هي طوابير غير قابلة للحجز. تحجز الطوابير القابلة للحجز حتى تنتهي من عملها أو تنتهي المهلة ، لكن الطوابير غير القابلة للحجز لا تفعل ذلك. بعض الطوابير هي Deques وبعض الطوابير هي PriorityQueues.
عمليات طابور الحجز
بالإضافة إلى نموذجين من عمليات الطابور ، تدعم طوابير الحجز نموذجين إضافيين كما هو موضح أدناه.
Operation | Throws exception | Special value | Blocks | Times out |
---|---|---|---|---|
Insert | add(e) | offer(e) | put(e) | offer(e, time, unit) |
Remove | remove() | poll() | take() | poll(time, unit) |
Examine | element() | peek() | N/A | N/A |
تحجز بعض العمليات حتى تنتهي من عملها ، وتحجز الأخرى حتى تنتهي المهلة. هذا كل شيء في جولة سريعة عن الطابور في جافا. آمل أن تساعدك هذه أمثلة طوابور جافا في البدء في برمجة مجموعة الطابور. يرجى ترك تعليق إذا أعجبك البرامج التعليمية الخاصة بي أو إذا كان لديك أي اقتراحات أو مشاكل أو أخطاء في الكتابة. شكرا لك.
Source:
https://www.digitalocean.com/community/tutorials/java-queue