За повечето хора думата "опашка" предизвиква много малко приятни асоциации. Но днес говорим за различни опашки — Java опашки. В Java опашката е всичко, което наследява интерфейса Queue , който от своя страна разширява интерфейса Collection . Това означава, че опашките могат да се третират като колекции.
Опашките в Java поддържат два принципа на работа: FIFO и LIFO .
Принципът FIFO (First In, First Out) управлява обикновена опашка — първият елемент, добавен към опашката, е първият, който я напуска.
Принципът LIFO (Last In, First Out) описва поведението на стека — последният елемент, добавен към опашката, е първият, който я напуска. Например, ето How работите с тесте карти: взимате карти една по една от горната, докато стигнете до дъното на тестето.
Йерархията на опашката в Java изглежда така:
Тук можете да видите, че Queue има 3 класа за изпълнение: LinkedList , ArrayDeque и PriorityQueue . LinkedList и ArrayDeque директно наследяват не Queue , а Deque .
Deque е интерфейс, добавен в Java 6. Той включва няколко метода, които са полезни за опашки и позволява на опашката да функционира като двустранна (or двупосочна) опашка. Това означава, че може да бъдеFIFOиLIFO.
Един от двата наследника на интерфейса Deque е ArrayDeque . Той поддържа опашка с двоен край, която ви позволява да вмъквате и премахвате елементи от двата края. Освен това е динамичен масив, който автоматично нараства по размер.
Има и клас PriorityQueue , който е пряк наследник на Queue : той се държи различно от класовете, които имплементират Deque .
PriorityQueue е опашка с приоритет, която организира елементи според естествения им ред по подразбиране. Тук сортирането използва интерфейсите Comparable и Comparator . Принципът е същият като при TreeSet or TreeMap — класове, които използват интерфейса Comparable и имат собствен ред на сортиране.
PriorityQueue<String> priorityQueue = new PriorityQueue<>(Comparator.comparingInt(String::length));
priorityQueue.add("Andrew");
priorityQueue.add("John");
priorityQueue.add("Rob");
while (!priorityQueue.isEmpty()) {
System.out.println(priorityQueue.remove());
}
Ако изпълните този пример, ето Howво ще видите в конзолата:
Джон
Андрю
Тъй като работим с опашки, а не с обикновени колекции, трябва да премахнем елементите от списъка. За да направим това, използваме тази конструкция:
while (!priorityQueue.isEmpty()) {
System.out.println(priorityQueue.remove());
}
Интерфейсът Deque наследява методите Queue и добавя няколко свои интересни метода:
void addFirst(E obj) | Добавя елемента obj в началото на опашката |
void addLast(E obj) | Добавя obj елемента в края на опашката |
E getFirst() | Връща първия елемент от опашката |
E getLast() | Връща последния елемент от опашката |
boolean offerFirst(E obj) | Добавя obj елемента в началото на опашката и връща true , ако елементът е добавен. В противен случай връща false . |
булева оферта Последна (E obj) | Добавя obj елемента в края на опашката и връща true , ако елементът е добавен. В противен случай връща false . |
E pop() | Получава първия елемент от опашката и го премахва |
void push(E obj) | Добавя елемента obj в началото на опашката |
E peekFirst() | Връща (но не премахва) първия елемент от опашката |
E peekLast() | Връща (но не премахва) последния елемент от опашката |
E pollFirst() | Връща и премахва първия елемент от опашката. Връща нула , ако няма елементи. |
E pollLast() | Връща и премахва последния елемент от опашката. Връща нула , ако няма елементи. |
E removeLast() | Връща и премахва първия елемент от опашката. Извежда изключение, ако няма елементи. |
E removeFirst() | Връща и премахва последния елемент от опашката. Извежда изключение, ако няма елементи. |
boolean removeFirstOccurrence(Object obj) | Премахва първото срещане на obj от опашката |
boolean removeLastOccurrence(Object obj) | Премахва последното срещане на obj от опашката |
Нека сега разгледаме някои от тези методи на практика.
Първо, нека добавим елемент към опашка:
Deque<String> deque = new ArrayDeque<>();
deque.add("Apple"); // Adds "Apple" to the end of the queue
deque.addFirst("Orange"); // Adds "Orange" to the front of the queue
deque.addLast("Pineapple"); // Adds "Pineapple" to the end of the queue
System.out.println(deque);
Сега нека вземем стойности от опашка:
Deque<String> deque = new ArrayDeque<>();
deque.add("Apple");
deque.addFirst("Orange");
deque.addLast("Pineapple");
System.out.println("The first element is: "+ deque.getFirst());
System.out.println("The last element is: " + deque.getLast());
}
Този code показва първия и последния елемент от опашката.
Последният елемент е: ананас
Deque<String> deque = new ArrayDeque<>();
deque.add("Apple");
deque.addFirst("Orange");
deque.addLast("Pineapple");
deque.add("Lemon");
System.out.println(deque.pop()); // Get and remove the first element of the queue
System.out.println(deque.poll()); // Get and remove the first element of the queue
System.out.println(deque);
Изпълнявайки този code, получаваме:
ябълка
[ананас, лимон]
Разликата между pop() и poll() е, че pop() ще хвърли NoSuchElementException , ако списъкът е празен списък, но poll() ще върне null .
Сега ще разгледаме методите pollFirst() и pollLast() .
Deque<String> deque = new ArrayDeque<>();
deque.add("Apple");
deque.addFirst("Orange");
deque.addLast("Pineapple");
deque.add("Lemon");
System.out.println(deque.pollFirst()); // Get and remove the first element of the queue
System.out.println(deque.pollLast()); // Get and remove the last element of the queue.
System.out.println(deque);
лимон
[ябълка, ананас]
И двата метода връщат и премахват стойност от опашката.
Ето пример за използване на методите peekFirst() и peekLast() :
Deque<String> friends = new ArrayDeque<>();
friends.add("John");
friends.add("Rob");
friends.add("Greg");
friends.add("Max");
friends.add("Oliver");
System.out.println("The first element is: " + friends.peekFirst());
System.out.println("The last element is: " + friends.peekLast());
System.out.println(friends);
Последният елемент е: Оливър
[Джон, Роб, Грег, Макс, Оливър]
И двата метода връщат първия/последния елемент от опашката и не ги премахват. Ако опашката е празна, ще се върне null .
Много добре! Днес научихме How да работим с опашки в Java. Сега знаете How да ги използвате на практика.
GO TO FULL VERSION