Tại sao lớp Java Vector (và Stack) bị coi là lỗi thời hoặc không dùng nữa?


677

Tại sao Vector Vector được coi là một lớp kế thừa, lỗi thời hoặc không dùng nữa?

Không sử dụng hợp lệ khi làm việc với đồng thời?

Và nếu tôi không muốn đồng bộ hóa thủ công các đối tượng và chỉ muốn sử dụng bộ sưu tập an toàn luồng mà không cần tạo các bản sao mới của mảng bên dưới (như CopyOnWriteArrayListvậy), thì có ổn không khi sử dụng Vector?

Thế còn Stack, một lớp con của Vectorcái gì, tôi nên sử dụng cái gì thay vì nó?


Họ đã lỗi thời, nhưng họ không bị phản đối.
Hầu tước Lorne

Câu trả lời:


655

Vectorđồng bộ hóa trên từng hoạt động riêng lẻ. Đó gần như không bao giờ là những gì bạn muốn làm.

Nói chung, bạn muốn đồng bộ hóa toàn bộ chuỗi hoạt động. Đồng bộ hóa các hoạt động riêng lẻ đều kém an toàn hơn ( Vectorví dụ: nếu bạn lặp qua một , bạn vẫn cần phải mở khóa để tránh bất kỳ ai khác thay đổi bộ sưu tập cùng một lúc, điều này sẽ gây ra một ConcurrentModificationExceptionluồng lặp) nhưng cũng chậm hơn ( Tại sao lấy ra một khóa liên tục khi một lần sẽ là đủ)?

Tất nhiên, nó cũng có chi phí khóa ngay cả khi bạn không cần.

Về cơ bản, đó là một cách tiếp cận rất thiếu sót để đồng bộ hóa trong hầu hết các tình huống. Như ông Brian Henk đã chỉ ra, bạn có thể trang trí một bộ sưu tập bằng cách sử dụng các cuộc gọi như Collections.synchronizedList- thực tế Vectorkết hợp cả việc thực hiện bộ sưu tập "mảng đã thay đổi kích thước" với bit "đồng bộ hóa mọi thao tác" là một ví dụ khác về thiết kế kém; phương pháp trang trí cho sự phân tách rõ ràng hơn của mối quan tâm.

Đối với một Stacktương đương - Tôi sẽ nhìn vào Deque/ ArrayDequeđể bắt đầu.


108
"Nói chung, bạn muốn đồng bộ hóa toàn bộ chuỗi hoạt động." - Đó là điểm! Cảm ơn!
fjsj

7
trong phiên bản nào của java Deprecated Vector (Hiện tại tôi đã sử dụng Java7). Nhưng tôi chưa bao giờ thấy là một Deprecated? Tạm biệt cách giải thích tuyệt vời ... + 1
Samir Mangroliya

17
@Samir: Nó không chính thức bị phản đối - chỉ là ArrayList thường được ưa thích hơn.
Jon Skeet

26
@Samir: Không, tôi sẽ không cố gắng dự đoán tương lai.
Jon Skeet

5
đơn giản là gr8. vector không phản đối nó một di sản class.There phải khác biệt giữa phản đối và di sản và có có thấy stackoverflow.com/questions/2873254/...
Prashant Shilimkar

82

Vector là một phần của 1.0 - việc triển khai ban đầu có hai nhược điểm:

1. Đặt tên: vectơ thực sự chỉ là các danh sách có thể được truy cập dưới dạng mảng, do đó, nó nên được gọi ArrayList(đó là sự thay thế Bộ sưu tập Java 1.2 Vector).

2. Concurrency: Tất cả các get(), set()phương pháp này synchronized, vì vậy bạn có thể không tốt hạt kiểm soát đồng bộ hóa.

Không có nhiều sự khác biệt giữa ArrayListVector, nhưng bạn nên sử dụng ArrayList.

Từ tài liệu API.

Kể từ nền tảng Java 2 v1.2, lớp này đã được trang bị thêm để triển khai giao diện Danh sách, làm cho nó trở thành thành viên của Khung công tác Bộ sưu tập Java. Không giống như các triển khai bộ sưu tập mới, Vector được đồng bộ hóa.


Danh sách nào có thể được truy cập dưới dạng mảng? ArrayList không phải là một tên rất ngắn hoặc hấp dẫn, đó có thể là lý do tại sao vectơ được sử dụng ở nơi khác (ví dụ: STL).
dhardy

6
@dhardy Liệt kê với một mảng là triển khai cơ bản của nó. Có ArrayList, LinkedListvv, tất cả đều thực hiện giao diện List, vì vậy nếu bạn muốn sử dụng các Listphương pháp mà không cần phải biết những gì thực hiện cơ bản thực chất là bạn chỉ có thể mất một Listnhư một tham số để phương pháp, vv Điều này cũng áp dụng đối với người thực hiện Mapvà như thế. Trong khi đó, C ++ có một std::arraylớp, đây chỉ là một sự thay thế dựa trên khuôn mẫu cho các mảng có chiều dài tĩnh kiểu C.
JAB

41

Bên cạnh các câu trả lời đã được nêu về việc sử dụng Vector, Vector cũng có một loạt các phương thức xoay quanh việc liệt kê và truy xuất phần tử khác với giao diện Danh sách và các nhà phát triển (đặc biệt là những người đã học Java trước 1.2) có thể có xu hướng sử dụng chúng nếu chúng ở trong mã. Mặc dù Số liệt kê nhanh hơn, nhưng họ không kiểm tra xem bộ sưu tập có bị sửa đổi trong quá trình lặp không, điều này có thể gây ra sự cố hay không và do Vector có thể được chọn để đồng bộ hóa - với quyền truy cập từ nhiều luồng, điều này khiến nó trở thành một vấn đề đặc biệt nguy hiểm. Việc sử dụng các phương thức này cũng kết hợp rất nhiều mã với Vector, do đó sẽ không dễ dàng thay thế nó bằng cách triển khai Danh sách khác.


14

Bạn có thể sử dụng phương thức Đồng bộ hóa / Danh sách trong java.util.Collectionđể có được bộ sưu tập an toàn luồng từ một phương pháp không an toàn luồng.


2
Tại sao điều này tốt hơn vector?
fjsj

8
Như Jon đã đề cập, Vector sẽ không thực hiện tốt và phương pháp này cho phép bạn chọn khi nào nên thực hiện đồng bộ hóa. Nó hoàn toàn là một vấn đề thiết kế. Bạn nên sử dụng ArrayList trên Vector vì bạn nên mặc định truy cập không đồng bộ.
Brian Henk

Làm thế nào để trả lời câu hỏi này?
Hầu tước Lorne

8

java.util.Stackkế thừa chi phí đồng bộ hóa java.util.Vector, thường không được chứng minh.

Nó thừa hưởng nhiều hơn thế, mặc dù. Thực tế đó java.util.Stack extends java.util.Vectorlà một sai lầm trong thiết kế hướng đối tượng. Những người theo chủ nghĩa thuần túy sẽ lưu ý rằng nó cũng cung cấp rất nhiều phương thức ngoài các hoạt động truyền thống được liên kết với một ngăn xếp (cụ thể là: đẩy, bật, nhìn trộm, kích thước). Nó cũng có thể làm được search, elementAt, setElementAt, remove, và nhiều hoạt động truy cập ngẫu nhiên khác. Về cơ bản, người dùng không thể sử dụng các hoạt động không ngăn xếp của Stack.

Đối với các lý do hiệu năng và thiết kế OOP này, JavaDoc đãjava.util.Stack khuyến nghị ArrayDequethay thế tự nhiên. (Một deque không chỉ là một chồng, nhưng ít nhất nó bị hạn chế thao túng hai đầu, thay vì cung cấp quyền truy cập ngẫu nhiên vào mọi thứ.)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.