2013-01-20 37 views
7

Queue Trong Java cung cấp cấu trúc dữ liệu FIFO. Theo những gì tôi đã học được, hàng đợi có trách nhiệm tuân thủ hành vi đầu tiên trong lần đầu tiên. Nói cách khác, bạn không thể xóa các mục từ giữa hàng đợi. Tuy nhiên, trong Java chúng ta có thể loại bỏ các phần tử xếp hàng ngẫu nhiên bằng cách sử dụng một iterator.Hàng đợi trong Java cho phép xóa phần tử ngẫu nhiên. điều này có tệ không?

Đây có phải là thiết kế đóng gói không đúng không? hoặc cấu trúc dữ liệu hàng đợi có cho phép điều này không?

Queue<String> queue = new LinkedList<String>(); 
queue.add("e1"); 
queue.add("e2"); 
queue.add("e3"); 
queue.add("e4"); 

queue.remove("e3"); 
+4

Từ các tài liệu: "_Queues thường, nhưng không nhất thiết, đặt hàng các yếu tố trong một FIFO (đầu tiên trong đầu tiên-out) cách. Trong số các trường hợp ngoại lệ là hàng đợi ưu tiên, thứ tự các yếu tố theo một so sánh được cung cấp ator, hoặc các phần tử tự nhiên của các phần tử, và hàng đợi LIFO (hoặc ngăn xếp) để sắp xếp các phần tử LIFO (cuối cùng-ra-trước-ra) ...._ "Đọc thêm [ở đây] (http://docs.oracle. com/javase/6/docs/api/java/util/Queue.html) – jahroy

+0

Tôi nghĩ rằng đó là để làm nổi bật hành vi của hàng đợi ưu tiên và triển khai như vậy. –

+0

Xuất phát từ 'Queue mở rộng Bộ sưu tập'. Đó là một trong hai hoặc 'UnsupportedOperationException' và tôi ghét cả hai đều như nhau. Đó là một bất ngờ lớn khi chuyển từ 'LSP' nghiêm ngặt của' C++' sang 'Java'. –

Trả lời

6

Queue rõ ràng là thừa hưởng một số chức năng được thêm này bằng cách là một phần của phân cấp Collection.Từ quan điểm đa hình, có lợi khi có Queue hoạt động giống như bất kỳ Collection nào khác vì nó làm tăng tính di động của cấu trúc dữ liệu.

Từ quan điểm thiết kế, tôi sẽ không nói rằng điều đó là xấu nhất thiết. Hãy tưởng tượng một hàng đợi/dòng tại một cửa hàng tạp hóa. Có những tình huống mà khách hàng có thể cần phải bị xóa khỏi phần giữa của dòng. Điều này thực hiện cụ thể của một hàng đợi hỗ trợ đó, mà có thể hữu ích.

Trong khi bạn có thể tranh luận rằng phương pháp bổ sung có thể cho phép bạn chụp mình trong bàn chân, bạn có thể dễ dàng tạo ra một thực hiện Queue không cho phép những thứ như remove(Object) hoặc iterator.remove() nếu bạn muốn có một nghiêm ngặt Queue.

3

mỗi những gì tôi học được, hàng đợi có một số trách nhiệm tuân thủ đầu tiên-trong-đầu-ra hành vi.

Bạn có thể đã đọc một cuốn sách văn bản hoặc một số ghi chú bài giảng hoặc một cái gì đó mô tả cách hoạt động của hàng đợi FIFO lý tưởng. Nhưng những gì bạn đã thất bại trong việc nhận ra là không phải tất cả các hàng đợi đều là FIFO. Không phải trong thế giới thực, và không phải trong các hệ thống máy tính. (Ví dụ, nếu (giả thuyết) Tổng thống Obama đã đi đến một nhà hàng MacDonalds bận rộn, bạn sẽ thấy rằng ông đã ngay lập tức di chuyển đến phía trước của hàng đợi. Đó là một hàng đợi hành xử trong một thời trang không FIFO.)

Dù sao , Java Queue là một giao diện cho bất kỳ loại hàng đợi nào, không chỉ hàng đợi FIFO. Nó cũng hỗ trợ các hàng đợi ưu tiên và bất kỳ ngữ nghĩa xếp hàng nào khác mà bạn có thể mơ ước ... nếu bạn quan tâm đến việc cung cấp lớp triển khai của riêng bạn.

Điểm khác là hoạt động remove(E) không cung cấp hoạt động "vui lòng khách hàng tiếp theo". Nó tương đương với một khách hàng quyết định rằng họ thực sự thích pizza ... và bước ra khỏi cửa. Một hàng đợi lý tưởng không hỗ trợ điều này, nhưng các lớp thư viện có thể sử dụng được ... vì các ứng dụng cần có khả năng thực hiện loại điều này.

Điểm mấu chốt là Java Collection phân cấp lớp (bao gồm đầu mối Queue) được thiết kế hữu ích và dễ sử dụng, thay vì cứng nhắc phù hợp với mô hình trừu tượng của cấu trúc dữ liệu của ai đó.


Nhưng sau đó Queue có thể cho phép một phương pháp sneakIn, cho phép bạn lẻn vào giữa một hàng đợi - đâu là phương pháp đó?

Vâng, vì hầu hết các ứng dụng thực sự không cần nó, nó không có ở đó. (Nếu đó là trường hợp sử dụng phổ biến, một phương thức như vậy sẽ được cung cấp, trong các lớp triển khai hàng đợi cụ thể ngay cả khi không ở trong giao diện Queue.)

Một lần nữa, các lớp và giao diện Java được chỉ định cho tiện ích và khả năng sử dụng của chúng các chương trình thực sự, chứ không phải (trong trường hợp này) để chúng có thể mô hình POTUS trong một phần bánh burger.

Có lẽ tôi đã được rửa sạch bằng các định nghĩa sách văn bản và các phòng thí nghiệm C/C++ mà tôi đã làm ở trường.

Một giải thích khác là bạn nhầm lẫn mục đích thực sự của các định nghĩa, v.v.

+0

Vâng, tôi đã nghĩ về những ví dụ tương tự. Nhưng sau đó 'Queue' có thể cho phép một phương thức' sneakIn', cho phép bạn lẻn vào giữa hàng đợi - phương thức đó ở đâu? Có lẽ tôi là não được rửa sạch bởi các định nghĩa sách văn bản và các phòng thí nghiệm C/C++ mà tôi đã làm ở trường. –

1

Hàng đợi Java không nhất thiết phải là FIFO. API hàng đợi cho biết

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

Nó phụ thuộc vào việc triển khai, ví dụ PriorityQueue không phải là FIFO nhưng LinkedList mà bạn đã sử dụng là FIFO.

Queue.remove() API không nói nó loại bỏ một yếu tố ngẫu nhiên, nó nói

Retrieves and removes the head of this queue. 

Trong ví dụ của bạn nó phải được

queue.remove(); 

và nó sẽ loại bỏ e1

+0

Có, nhưng quá tải 'xóa' cho phép bạn loại bỏ mục từ giữa hàng đợi, mà là chống lại các nguyên tắc ít ngạc nhiên nhất đối với tôi. –

+0

Vâng, nhưng điều này sẽ phá vỡ hợp đồng Queue.remove, nó nói "loại bỏ phần đầu của hàng đợi" –

Các vấn đề liên quan