Я узнал, что в Java класс LinkedList
реализует интерфейсы Deque
и List
. И это несколько сбивало с толку.
В учебной программе по информатике я никогда не учил, что очередь может быть списком, или, точнее, очередь может вести себя как список. То есть, есть вещи, которые могут делать списки, но очереди не могут. Но список может вести себя как очередь. Например, интерфейс List
имеет следующие методы:
add(E e)
add(int index, E element)
Но Queue
имеет только следующее:
add(E e)
Поэтому ясно, что Queue
не допускается вставлять по определенному индексу, что разрешено в List
. То же самое относится к другим операциям, таким как Queue.remove()
vs. List.remove(int index)
, List.get(int index)
и Queue.peek()
. Другими словами, список представляет собой более обобщенную структуру данных и может эмулировать Queue
.
Теперь способность эмулировать отличается от наличия подмножества контракта. То есть Queue
запрещает определенные операции (индексирование) List
и позволяет определенные операции выполняются только определенным образом (вставлять только в хвост и удалять только из головы). Таким образом, Queue
действительно не делает "дополнение" к контрактам List
. Именно поэтому Queue
не расширяет рамки List
in Java, но расширяет интерфейс Collection
. Я считаю, что это также, почему это неправильно для любого класса, чтобы реализовать оба, как и Queue
контракта конфликты с договором List
(поэтому они раскошелиться из Collection
интерфейса отдельно). Однако LinkedList
реализует оба интерфейса.
Я также наткнулся на этот ответ:
Реализация
LinkedList
выполняется, чтобы удовлетворить контрактDeque
, поэтому почему бы не реализовать его интерфейс?
Я до сих пор не понимаю, как мы можем сказать, что реализация LinkedList
выполняется, чтобы удовлетворить контракт Deque
. Понятие очереди не допускает вставки с произвольным индексом. Следовательно, интерфейс Queue
не имеет таких методов.
Однако мы можем только заключать контракты через интерфейсы и не можем запретить реализацию определенных методов. Будучи списком (имея "Список" в его имени), я считаю неправильным иметь методы очереди peek()
, pop()
и add(int index, E element)
в LinkedList
.
Я полагаю, вместо этого у нас должен быть отдельный класс LinkedQueue
который может связать реализацию для очереди, похожую на LinkedBlockingQueue
которая содержит связанную реализацию BlockingQueue
.
Также обратите внимание, что LinkedList
является единственным классом, который наследуется от обоих семейств списков и очередей, т.е. Нет другого класса, который реализует как List
и Queue
(AFAIK). Может ли это быть свидетельством того, что LinkedList
плохо сделано?
Я просто ошибаюсь и думаю излишне?