Mengapa kelas Java Vector (dan Stack) dianggap usang atau usang?


677

Mengapa Java Vector dianggap sebagai kelas warisan, usang atau usang?

Bukankah penggunaannya valid ketika bekerja dengan concurrency?

Dan jika saya tidak ingin menyinkronkan objek secara manual dan hanya ingin menggunakan koleksi thread-safe tanpa perlu membuat salinan baru dari array yang mendasarinya (seperti CopyOnWriteArrayListhalnya), maka apakah boleh digunakan Vector?

Bagaimana dengan Stack, yang merupakan subkelas dari Vector, apa yang harus saya gunakan daripada itu?


Mereka usang, tetapi mereka tidak ditinggalkan.
Marquis of Lorne

Jawaban:


655

Vectordisinkronkan pada setiap operasi individu. Itu hampir tidak pernah ingin Anda lakukan.

Secara umum Anda ingin menyinkronkan seluruh urutan operasi. Menyinkronkan masing-masing operasi kurang aman (jika Anda beralih pada Vector, misalnya, Anda masih perlu mengeluarkan kunci untuk menghindari orang lain mengubah koleksi pada saat yang sama, yang akan menyebabkan a ConcurrentModificationExceptiondi utas pengulangan) tetapi juga lebih lambat ( mengapa mengambil kunci berulang kali ketika sekali sudah cukup)?

Tentu saja, itu juga memiliki penguncian bahkan ketika Anda tidak perlu.

Pada dasarnya, ini adalah pendekatan yang sangat cacat untuk sinkronisasi dalam sebagian besar situasi. Seperti yang ditunjukkan oleh Tuan Brian Henk , Anda dapat menghias koleksi menggunakan panggilan seperti Collections.synchronizedList- fakta yang Vectormenggabungkan implementasi koleksi "array yang diubah ukurannya" dengan bit "sinkronisasi setiap operasi" adalah contoh lain dari desain yang buruk; pendekatan dekorasi memberikan pemisahan keprihatinan yang lebih bersih.

Adapun Stacksetara - saya akan melihat Deque/ ArrayDequemulai dengan.


108
"Umumnya Anda ingin menyinkronkan seluruh urutan operasi." - Itu intinya! Terima kasih!
fjsj

7
di mana versi java Deprecated Vector (Saat ini saya menggunakan Java7). Tapi saya tidak pernah melihat sebagai Deprecated? Bye the Way Penjelasan bagus ... + 1
Samir Mangroliya

17
@ Samir: Ini tidak secara resmi ditinggalkan - hanya saja ArrayList umumnya disukai.
Jon Skeet

26
@ Samir: Tidak, saya tidak akan mencoba untuk memprediksi masa depan.
Jon Skeet

5
cukup gr8. vektor tidak ditinggalkan, ini adalah kelas warisan. Harus ada perbedaan antara usang dan warisan dan ya ada lihat stackoverflow.com/questions/2873254/…
Prashant Shilimkar

82

Vektor adalah bagian dari 1.0 - implementasi asli memiliki dua kelemahan:

1. Penamaan: vektor benar-benar hanya daftar yang dapat diakses sebagai array, sehingga seharusnya dipanggil ArrayList(yang merupakan pengganti Java 1.2 Collections untuk Vector).

2. Concurrency: Semua get(), set()metode yang synchronized, sehingga Anda tidak dapat memiliki berbutir halus kontrol atas sinkronisasi.

Tidak ada banyak perbedaan antara ArrayListdan Vector, tetapi Anda harus menggunakannya ArrayList.

Dari dokumen API.

Pada platform Java 2 v1.2, kelas ini dipasang untuk mengimplementasikan antarmuka Daftar, menjadikannya anggota Java Collections Framework. Berbeda dengan implementasi koleksi baru, Vector disinkronkan.


Daftar yang dapat diakses sebagai array? ArrayList bukan nama yang sangat pendek atau menarik, yang mungkin menjadi alasan mengapa vektor digunakan di tempat lain (misalnya STL).
dhardy

6
@dhardy List dengan array sebagai implementasi yang mendasarinya. Ada ArrayList, LinkedList, dll, yang semuanya menerapkan antarmuka List, jadi jika Anda ingin memanfaatkan Listmetode tanpa harus mengetahui apa yang mendasari pelaksanaan sebenarnya Anda hanya dapat mengambil Listsebagai parameter untuk metode, dll yang sama berlaku untuk pelaksana Mapdan seterusnya. Sementara itu, C ++ memang memiliki std::arraykelas, yang hanya pengganti berbasis template untuk array panjang statis C-style.
JAB

41

Selain jawaban yang sudah dinyatakan tentang penggunaan Vektor, Vektor juga memiliki banyak metode seputar pencacahan dan pengambilan elemen yang berbeda dari antarmuka Daftar, dan pengembang (terutama mereka yang mempelajari Java sebelum 1.2) dapat cenderung menggunakannya jika mereka berada di kode. Meskipun Pencacahan lebih cepat, mereka tidak memeriksa apakah koleksi telah diubah selama iterasi, yang dapat menyebabkan masalah, dan mengingat bahwa Vector mungkin dipilih untuk sinkronisasi - dengan akses yang hadir dari beberapa utas, ini membuatnya menjadi masalah yang sangat berbahaya. Penggunaan metode ini juga memasangkan banyak kode ke Vector, sehingga tidak akan mudah untuk menggantinya dengan implementasi Daftar yang berbeda.


14

Anda dapat menggunakan synchronizedCollection / Daftar metode java.util.Collectionuntuk mendapatkan koleksi benang-aman dari satu non-benang-aman.


2
mengapa ini lebih baik daripada vektor?
fjsj 06

8
Seperti yang disebutkan oleh Jon, Vector tidak akan bekerja dengan baik, dan metode ini memungkinkan Anda untuk memilih kapan ide yang baik untuk melakukan sinkronisasi. Ini benar-benar masalah desain. Anda harus menggunakan ArrayList melalui Vector karena Anda seharusnya menggunakan akses non-sinkronisasi.
Brian Henk

Bagaimana ini menjawab pertanyaan?
Marquis of Lorne

8

java.util.Stackmewarisi overhead sinkronisasi java.util.Vector, yang biasanya tidak dibenarkan.

Ini mewarisi lebih banyak dari itu. Fakta itu java.util.Stack extends java.util.Vectoradalah kesalahan dalam desain berorientasi objek. Purist akan mencatat bahwa ia juga menawarkan banyak metode di luar operasi yang secara tradisional dikaitkan dengan stack (yaitu: push, pop, peek, size). Ini juga mungkin untuk melakukan search, elementAt, setElementAt, remove, dan banyak operasi random-akses lainnya. Pada dasarnya terserah kepada pengguna untuk menahan diri dari menggunakan operasi non-stack Stack.

Untuk alasan kinerja dan desain OOP ini, JavaDoc untukjava.util.Stack merekomendasikan ArrayDequesebagai pengganti alami. (Deque lebih dari sekadar tumpukan, tapi setidaknya itu terbatas untuk memanipulasi kedua ujungnya, daripada menawarkan akses acak ke semuanya.)

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.