Queue, Deque
Тема дорожной карты · Java
Queue и Deque — фундаментальные интерфейсы в Java Collections framework, моделирующие упорядочивание элементов по принципу FIFO (первым пришёл — первым вышел) и с обоих концов, обеспечивая потокобезопасную и однопоточную постановку задач в очередь, обход в ширину и алгоритмы скользящего окна на JVM. Интерфейс Queue расширяет Collection методами offer(e), poll() и peek(), возвращающими null или false при неудаче вместо бросания исключений, тогда как Deque (двусторонняя очередь) расширяет Queue методами addFirst, addLast, pollFirst, pollLast и peekFirst/peekLast для поддержки семантики как стека, так и очереди в одной структуре. Ключевые реализации включают ArrayDeque — предпочтительную реализацию Queue и Deque общего назначения на основе изменяемого кольцевого массива, быстрее LinkedList в большинстве случаев, — и PriorityQueue для упорядочивания на основе кучи по естественному порядку или Comparator. Для Concurrency java.util.concurrent предлагает ArrayBlockingQueue, LinkedBlockingQueue, PriorityBlockingQueue, ConcurrentLinkedQueue и LinkedTransferQueue, все построенные на алгоритмах без блокировок или с мелкозернистыми блокировками, лежащих в основе отправки задач в ExecutorService и ForkJoinPool. Понимание Queue и Deque в Java обязательно для реализации рабочих очередей в асинхронной обработке Spring, шин событий, ограничителей скорости и конвейеров производитель-потребитель с использованием CompletableFuture или Virtual Threads.
Как это работает
Queue, Deque даёт List (ArrayList, LinkedList), Set (HashSet, TreeSet, LinkedHashSet), Map (HashMap, TreeMap, LinkedHashMap, ConcurrentHashMap), Queue (ArrayDeque, PriorityQueue). Все реализуют Collection (Map отдельно). Streams API (stream(), filter(), map(), collect()) заменяет большинство явных циклов. Immutable factory-методы: List.of(...), Map.of(...), Set.of(...) — возвращают read-only view (бросают при мутации).
Когда применять
ArrayList по умолчанию вместо LinkedList — array-backed доступ драматически быстрее для почти любой реальной нагрузки. HashMap — кроме случаев, где важен порядок (LinkedHashMap для insertion order, TreeMap для sorted). ConcurrentHashMap — для shared-state map (никогда не оборачивайте HashMap в Collections.synchronizedMap в новом коде). Stream — для трансформаций; циклы — для side-effect-обработки.
Типичные ошибки
Ловушки Queue, Deque: выбор LinkedList для "быстрых insert" без замеров (cache-miss затмевает алгоритмическое преимущество); Map<String, ...> с mutable ключевыми объектами (hashCode меняется — потерянные entry); List.of(...) и попытка добавить позже (UnsupportedOperationException); concurrent modification в for-цикле (CME — используйте removeIf или Iterator).