Очереди в Java позволяют удалить случайный элемент. это плохо?

Queue В Java предусмотрена структура данных FIFO. По тому, что я узнал, в очередях есть определенная ответственность придерживаться поведения "первым в первом". Другими словами, вы не можете удалять элементы из середины очереди. Однако в Java мы можем удалить элементы случайной очереди с помощью iterator.

Это плохая инкапсуляция дизайна? или это должна быть структура данных очереди?

Queue<string> queue = new LinkedList<string>();
queue.add("e1");
queue.add("e2");
queue.add("e3");
queue.add("e4");
queue.remove("e3");
</string></string>
3 ответа

Queue явно наследует некоторые из этих добавленных функциональных возможностей, будучи частью иерархии Collection. С полиморфной точки зрения полезно иметь Queue действовать как любой другой Collection, поскольку это повышает переносимость структуры данных.

С точки зрения дизайна, я бы не сказал, что это плохо. Представьте себе очередь/линию в продуктовом магазине. Бывают ситуации, когда клиент может быть удален из середины линии. Эта конкретная реализация очереди поддерживает это, что может быть полезно.

Пока вы можете утверждать, что дополнительные методы позволят вам застрелить себя в ноге, вы можете легко создать реализацию Queue, которая не позволяет такие вещи, как remove(Object) или iterator.remove(), если вы хотите, чтобы строгий Queue.


В соответствии с тем, что я узнал, в очередях есть определенная ответственность придерживаться поведения "первым-в-первых".

Вероятно, вы читали учебник или лекционные заметки или что-то, что описывает, как работает идеализированная очередь FIFO. Но вы не поняли, что не все очереди являются FIFO. Не в реальном мире, а не в компьютерных системах. (Например, если (предположительно) президент Обама отправился в оживленный ресторан MacDonalds, вы обнаружите, что он был немедленно перемещен в очередь перед очередью. Это очередь ведет себя не в FIFO.)

В любом случае, Java Queue - это интерфейс для любой очереди, а не только для очередей FIFO. Он также поддерживает очереди приоритетов и любую другую семантику очередей, о которой вы могли бы мечтать... если вы хотите предоставить свой собственный класс реализации.

Другой момент заключается в том, что операция remove(E) не предоставляет операцию "следующий клиент". Это эквивалент того, что клиент решил, что они действительно предпочли бы пиццу... и выйдя за дверь. Идеализированная очередь не поддерживает это, но используемые классы библиотек... потому что приложения должны иметь возможность делать такие вещи.

Суть в том, что иерархия классов Java Collection (в том числе ключ Queue) предназначена для удобства и простоты использования, а не для жесткой подгонки какой-то абстрактной модели структур данных.

Но тогда Queue может разрешить метод sneakIn, который позволяет вам проникнуть в середину очереди - где этот метод?

Ну, так как большинство реальных приложений это не нужно, его там нет. (Если бы это было обычным прецедентом, такой метод был бы предоставлен в конкретных классах реализации очереди, даже если не в интерфейсе Queue.)

Еще раз, классы Java и интерфейсы указаны для их полезности и удобства использования в реальных программах, а не (в данном случае), чтобы они могли моделировать POTUS в сумеречном гамбургере.

Возможно, я мозг омывается описаниями текстовых книг и лабораториями C/С++, которые я делал в школе.

Альтернативное объяснение состоит в том, что вы ошибочно приняли истинную цель определений и т.д.


Java Queue не обязательно FIFO. API очереди говорит

Queues typically, but do not necessarily, order elements in a FIFO (first-in-first-out) manner.

Это зависит от реализации, например PriorityQueue не является FIFO, а LinkedList, который вы использовали, это FIFO.

API Queue.remove() не говорит, что он удаляет случайный элемент, он говорит

Retrieves and removes the head of this queue.

В вашем примере это должно быть

queue.remove();

и он удалит e1

licensed under cc by-sa 3.0 with attribution.