Như đã đề cập trong các nhận xét, chúng tôi đã kiểm tra tốt giao diện Deque
cần được ưu tiên hơn.
Nhưng tôi sẽ cho bạn lý do vì sao không nên sử dụng Stack
.
Lúc đầu, Tài liệu Java. của Stack nói bản thân:
Một bộ hoàn chỉnh hơn và nhất quán của ngăn xếp hoạt động LIFO là cung cấp bởi giao diện deque và triển khai của nó, mà nên được sử dụng trong ưu tiên cho lớp này. Ví dụ:
Deque stack = new ArrayDeque();
Xem JavaDoc.
Vì vậy, vấn đề với lớp học Stack
là gì.
Giống như Martin Fowler đã được đề cập trong cuốn sách của ông Refactoring: Cải thiện thiết kế của Bộ luật hiện tại tại phương pháp refactoring Thay Inheritance với Phái đoàn, một Stack không nên kế thừa từ một Vector.
Một trong những ví dụ điển hình về thừa kế không phù hợp là tạo một lớp con vector. Java 1.1 thực hiện điều này trong các tiện ích của nó (các cậu bé nghịch ngợm!) [6, p. 288]
Thay vào đó, họ nên sử dụng đoàn như trong hình bên dưới, cũng có trong sách.
Xem thêm ở đây: Replace Inheritance with Delegation
Vì vậy, nhưng tại sao điều này là một vấn đề:
Bởi vì Stack chỉ có 5 Phương pháp:
- pop
- đẩy
- isEmpty
- tìm kiếm
kích thước
size()
và isEmpty()
được thừa kế từ lớp Vector
và các phương pháp khác từ Vector
không được sử dụng. Nhưng thông qua kế thừa, các phương thức khác được chuyển tiếp đến lớp Stack
mà không có ý nghĩa gì cả.
Và Fowler nói cho vấn đề này:
Bạn có thể sống với tình hình và sử dụng Công ước để nói rằng mặc dù nó là một lớp con, nó chỉ sử dụng một phần của lớp cha chức năng. Nhưng điều đó dẫn đến mã nói một điều khi ý định của bạn là cái gì đó khác — một sự nhầm lẫn bạn nên loại bỏ.
này làm tổn thương Interface Segregation Principle
mà nói:
KHÁCH HÀNG KHÔNG NÊN bị buộc phải phụ thuộc vào giao diện mà họ làm KHÔNG SỬ DỤNG.
Bạn có thể kiểm tra mã nguồn của Vector và Stack lớp và bạn sẽ thấy rằng các lớp Stack kế thừa spliterator
phương pháp và VectorSpliterator
innerClass từ lớp Vector
.
Phương pháp này được sử dụng bởi giao diện Collection
để impl. phiên bản mặc định của phương pháp dòng:
default Stream<E> More ...stream() {
return StreamSupport.stream(spliterator(), false);
}
Vì vậy, tránh đơn giản là sử dụng lớp Vector
và Stack
.
[6] Refactoring: Cải thiện thiết kế của Bộ luật Fowler hiện tại, Martin năm 1997
Tôi hy vọng đó là vì stack kéo dài Vector (trong đó duy trì trật tự chèn gốc; pop mang đến cho bạn ** ** đối tượng cuối cùng trong ngăn xếp). Bạn có nhận được kết quả tương tự bằng cách sử dụng Deque không? ArrayDeque ví dụ đẩy và bật ra phía trước, vì vậy nó sẽ cung cấp cho bạn thứ tự bạn muốn. – azurefrog
'Deque' (và các lớp thực thi của nó) thậm chí không có phương thức' stream() '. Câu hỏi đặt ra là liệu tôi có thể làm việc xung quanh nó không (tôi có thể viết rõ ràng vòng lặp của riêng mình). Lý do tại sao Stack sẽ cung cấp phương thức stream và stream nó theo cách sai, khi người ta mong đợi một lệnh LIFO cho sự lựa chọn của collection được sử dụng. – jbx
Theo [ArrayDeque API] (https://docs.oracle.com/javase/8/docs/api/java/util/ArrayDeque.html), nó có cùng phương thức 'stream()' từ java.util .Collection rằng [Stack] (https://docs.oracle.com/javase/8/docs/api/java/util/Stack.html). Tôi không có Java 8 ở đây mặc dù, vì vậy tôi không thể kiểm tra nó. – azurefrog