Java Queue – это интерфейс, доступный в пакете java.util и расширяет интерфейс java.util.Collection. Как и Java List, Java Queue представляет собой коллекцию упорядоченных элементов (или объектов), но выполняет операции вставки и удаления по-разному. Мы можем использовать Queue для хранения элементов перед их обработкой.
Java Queue
В этом разделе мы обсудим несколько важных моментов о Java Queue:
- Интерфейс java.util.Queue является подтипом интерфейса java.util.Collection.
- Как и в реальной очереди (например, в банке или на банкомате), Queue вставляет элементы в конец очереди и удаляет их из начала очереди.
- Java Queue представляет собой упорядоченный список элементов.
- Java Queue следует порядку FIFO при вставке и удалении элементов. FIFO означает “первым поступил — первым обслужен”.
- Java Queue поддерживает все методы интерфейса Collection.
- Наиболее часто используемые реализации Queue – это LinkedList, ArrayBlockingQueue и PriorityQueue.
- BlockingQueues не принимают элементы null. Если выполняется операция, связанная с null, то возникает исключение NullPointerException.
- BlockingQueues используются для реализации приложений с производителями и потребителями.
- BlockingQueues являются потокобезопасными.
- Все очереди, доступные в пакете java.util, являются неограниченными очередями, а очереди, доступные в пакете java.util.concurrent, являются ограниченными очередями.
- Все двусторонние очереди не являются потокобезопасными.
- ConcurrentLinkedQueue – это неограниченная потокобезопасная очередь на основе связанных узлов.
- Все очереди поддерживают вставку в хвост очереди и удаление из головы очереди, кроме двусторонних очередей.
- Двусторонние очереди являются очередями, но они поддерживают вставку и удаление элементов с обоих концов.
Диаграмма классов Java Queue
Интерфейс Java Queue расширяет интерфейс Collection. Интерфейс Collection расширяет интерфейс Iterable. Некоторые из часто используемых классов реализации очереди: LinkedList, PriorityQueue, ArrayBlockingQueue, DelayQueue, LinkedBlockingQueue, PriorityBlockingQueue и т.д. Абстрактный класс AbstractQueue предоставляет основную реализацию интерфейса Queue для упрощения процесса реализации очереди.
Методы Java Queue
В этом разделе мы обсудим некоторые полезные и часто используемые методы Java Queue:
- 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
Как 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 в очередь
Здесь мы можем изучить, как преобразовать массив 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 в массив
Здесь мы рассмотрим, как преобразовать очередь 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
Java Queue поддерживает все операции, поддерживаемые интерфейсом Collection, а также некоторые дополнительные операции. Он поддерживает практически все операции в двух формах.
- Один набор операций генерирует исключение в случае неудачи операции.
- Другой набор операций возвращает специальное значение в случае неудачи операции.
В следующей таблице кратко объясняются все общие операции с очередью.
Operation | Throws exception | Special value |
---|---|---|
Insert | add(e) | offer(e) |
Remove | remove() | poll() |
Examine | element() | peek() |
Мы рассмотрим каждую операцию более подробно и обсудим их с примерами в следующих разделах.
Операции вставки в Java Queue
В этом разделе мы подробно обсудим операцию вставки в Java Queue с примерами. Если эта операция выполняется успешно, она возвращает значение “true”. Как известно, у очереди есть две формы операции вставки:
- Queue.add(e):
Он генерирует исключение в случае неудачи операции.- Queue.offer(e):
Он возвращает специальное значение в случае неудачи операции.
ПРИМЕЧАНИЕ:- Здесь специальное значение может быть либо “false”, либо “null”
Операция add() в очереди
Операция add() используется для вставки нового элемента в очередь. Если операция вставки выполняется успешно, она возвращает значение “true”. В противном случае генерируется 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(), возникает исключение, как показано выше.
Операция предложения очереди
Операция offer() используется для вставки нового элемента в очередь. Если операция вставки выполняется успешно, она возвращает значение “true”. В противном случае она возвращает значение “false”. Давайте разработаем простой пример, чтобы продемонстрировать это функциональное действие.
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(), она возвращает значение “false”, как показано выше.
Операции удаления очереди в 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() в третий раз, он вернет значение null, как показано выше.
Операции проверки очереди в Java
В этом разделе мы обсудим операции проверки очереди в Java подробно с некоторыми полезными примерами. Если эта операция выполняется успешно, она возвращает элемент из головы очереди без его удаления. Как известно, у очереди есть две формы операции проверки:
- Queue.element():
Он генерирует исключение, если операция завершается неудачно.- Queue.peek():
Он возвращает специальное значение, если операция завершается неудачно.
ПРИМЕЧАНИЕ:- Здесь специальное значение может быть либо “false”, либо “null”
Операция Queue.element()
Операция 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() для пустой очереди, он выдаст исключение, как показано выше.
Операция peek() в очереди
Операция peek() используется для извлечения элемента из головы очереди без его удаления. Если операция проверки выполняется успешно, она возвращает элемент из головы очереди. В противном случае возвращается значение null. Давайте разработаем простой пример для демонстрации этой функциональности.
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() для пустой очереди, он вернет значение null, но НЕ выдаст исключение, как показано выше.
Категории очередей в Java
В Java существует много реализаций очередей. Мы можем широко классифицировать их на два следующих типа
- Ограниченные очереди
- Неограниченные очереди
Ограниченные очереди – это очереди, которые ограничены по вместимости, что означает, что мы должны указать максимальный размер очереди в момент ее создания. Например, ArrayBlockingQueue (см. предыдущий пример). Неограниченные очереди – это очереди, которые НЕ ограничены по вместимости, то есть мы не должны указывать размер очереди. Например, LinkedList (см. предыдущий пример). Все очереди, доступные в пакете java.util, являются неограниченными, а очереди, доступные в пакете java.util.concurrent, являются ограниченными. Другими словами, их можно широко классифицировать на два типа:
- Блокирующие очереди
- Неблокирующие очереди
Все очереди, реализующие интерфейс BlockingQueue, являются блокирующими очередями, остальные – неблокирующими. Блокирующие очереди блокируются, пока они не завершат свою работу или не истечет время, в то время как неблокирующие очереди этого не делают. Некоторые очереди – это двусторонние очереди, а некоторые – приоритетные очереди.
Операции с блокировкой очереди
В дополнение к двум формам операций очереди, блокирующие очереди поддерживают еще две формы, как показано ниже.
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 |
Некоторые операции блокируются, пока они не завершат свою работу, а другие – до истечения времени. Вот и всё, краткий обзор очереди в Java. Надеюсь, эти примеры очереди в Java помогут вам начать программирование с использованием коллекции очередей. Пожалуйста, оставьте комментарий, если вам нравятся мои учебники или у вас есть какие-либо предложения, проблемы или опечатки. Спасибо.
Source:
https://www.digitalocean.com/community/tutorials/java-queue